Compare commits
3 Commits
b219d193a2
...
20bae8b94d
Author | SHA1 | Date |
---|---|---|
Lennart Poettering | 20bae8b94d | |
Susant Sahani | 564ca98484 | |
Christian Rebischke | 597f905c76 |
3
NEWS
3
NEWS
|
@ -149,6 +149,9 @@ CHANGES WITH 244 in spe:
|
||||||
|
|
||||||
* libcryptsetup >= 2.0.1 is now required.
|
* libcryptsetup >= 2.0.1 is now required.
|
||||||
|
|
||||||
|
* systemd-resolved validates IP addresses in certificates now when GnuTLS
|
||||||
|
is being used.
|
||||||
|
|
||||||
CHANGES WITH 243:
|
CHANGES WITH 243:
|
||||||
|
|
||||||
* This release enables unprivileged programs (i.e. requiring neither
|
* This release enables unprivileged programs (i.e. requiring neither
|
||||||
|
|
|
@ -49,7 +49,7 @@ manpages = [
|
||||||
['pstore.conf', '5', ['pstore.conf.d'], 'ENABLE_PSTORE'],
|
['pstore.conf', '5', ['pstore.conf.d'], 'ENABLE_PSTORE'],
|
||||||
['resolvectl', '1', ['resolvconf'], 'ENABLE_RESOLVE'],
|
['resolvectl', '1', ['resolvconf'], 'ENABLE_RESOLVE'],
|
||||||
['resolved.conf', '5', ['resolved.conf.d'], 'ENABLE_RESOLVE'],
|
['resolved.conf', '5', ['resolved.conf.d'], 'ENABLE_RESOLVE'],
|
||||||
['runlevel', '8', [], 'ENABLE_UTMP'],
|
['runlevel', '8', [], ''],
|
||||||
['sd-bus-errors',
|
['sd-bus-errors',
|
||||||
'3',
|
'3',
|
||||||
['SD_BUS_ERROR_ACCESS_DENIED',
|
['SD_BUS_ERROR_ACCESS_DENIED',
|
||||||
|
|
|
@ -1902,6 +1902,19 @@
|
||||||
<filename>/etc/localtime</filename> symlink.</para></listitem>
|
<filename>/etc/localtime</filename> symlink.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>SendRawOption=</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Send a raw option with value via DHCPv4 server. Takes a DHCP option, data type and data
|
||||||
|
(option:type:value). The option ranges [1-254]. The type takes one of <literal>uint8</literal>,
|
||||||
|
<literal>uint16</literal>, <literal>uint32</literal>, <literal>ipv4address</literal>, or <literal>string</literal>.
|
||||||
|
Special characters in the data string may be escaped using
|
||||||
|
<ulink url="https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequences">C-style
|
||||||
|
escapes</ulink>. 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>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "dhcp-internal.h"
|
#include "dhcp-internal.h"
|
||||||
|
#include "dhcp-server-internal.h"
|
||||||
#include "memory-util.h"
|
#include "memory-util.h"
|
||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
#include "utf8.h"
|
#include "utf8.h"
|
||||||
|
@ -77,6 +78,32 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
|
||||||
*offset += 3 + optlen;
|
*offset += 3 + optlen;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
case SD_DHCP_OPTION_VENDOR_SPECIFIC: {
|
||||||
|
OrderedHashmap *s = (OrderedHashmap *) optval;
|
||||||
|
struct sd_dhcp_raw_option *p;
|
||||||
|
size_t l = 0;
|
||||||
|
Iterator i;
|
||||||
|
|
||||||
|
ORDERED_HASHMAP_FOREACH(p, s, i)
|
||||||
|
l += p->length + 2;
|
||||||
|
|
||||||
|
if (*offset + l + 2 > size)
|
||||||
|
return -ENOBUFS;
|
||||||
|
|
||||||
|
options[*offset] = code;
|
||||||
|
options[*offset + 1] = l;
|
||||||
|
|
||||||
|
*offset += 2;
|
||||||
|
|
||||||
|
ORDERED_HASHMAP_FOREACH(p, s, i) {
|
||||||
|
options[*offset] = p->type;
|
||||||
|
options[*offset + 1] = p->length;
|
||||||
|
memcpy(&options[*offset + 2], p->data, p->length);
|
||||||
|
*offset += 2 + p->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
if (*offset + 2 + optlen > size)
|
if (*offset + 2 + optlen > size)
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
|
|
|
@ -13,6 +13,16 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "time-util.h"
|
#include "time-util.h"
|
||||||
|
|
||||||
|
typedef enum DHCPRawOption {
|
||||||
|
DHCP_RAW_OPTION_DATA_UINT8,
|
||||||
|
DHCP_RAW_OPTION_DATA_UINT16,
|
||||||
|
DHCP_RAW_OPTION_DATA_UINT32,
|
||||||
|
DHCP_RAW_OPTION_DATA_STRING,
|
||||||
|
DHCP_RAW_OPTION_DATA_IPV4ADDRESS,
|
||||||
|
_DHCP_RAW_OPTION_DATA_MAX,
|
||||||
|
_DHCP_RAW_OPTION_DATA_INVALID,
|
||||||
|
} DHCPRawOption;
|
||||||
|
|
||||||
typedef struct DHCPClientId {
|
typedef struct DHCPClientId {
|
||||||
size_t length;
|
size_t length;
|
||||||
void *data;
|
void *data;
|
||||||
|
@ -27,6 +37,15 @@ typedef struct DHCPLease {
|
||||||
usec_t expiration;
|
usec_t expiration;
|
||||||
} DHCPLease;
|
} DHCPLease;
|
||||||
|
|
||||||
|
struct sd_dhcp_raw_option {
|
||||||
|
unsigned n_ref;
|
||||||
|
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t length;
|
||||||
|
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
struct sd_dhcp_server {
|
struct sd_dhcp_server {
|
||||||
unsigned n_ref;
|
unsigned n_ref;
|
||||||
|
|
||||||
|
@ -48,6 +67,8 @@ struct sd_dhcp_server {
|
||||||
struct in_addr *ntp, *dns, *sip;
|
struct in_addr *ntp, *dns, *sip;
|
||||||
unsigned n_ntp, n_dns, n_sip;
|
unsigned n_ntp, n_dns, n_sip;
|
||||||
|
|
||||||
|
OrderedHashmap *raw_option;
|
||||||
|
|
||||||
bool emit_router;
|
bool emit_router;
|
||||||
|
|
||||||
Hashmap *leases_by_client_id;
|
Hashmap *leases_by_client_id;
|
||||||
|
|
|
@ -127,6 +127,46 @@ int client_id_compare_func(const DHCPClientId *a, const DHCPClientId *b) {
|
||||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(dhcp_lease_hash_ops, DHCPClientId, client_id_hash_func, client_id_compare_func,
|
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(dhcp_lease_hash_ops, DHCPClientId, client_id_hash_func, client_id_compare_func,
|
||||||
DHCPLease, dhcp_lease_free);
|
DHCPLease, dhcp_lease_free);
|
||||||
|
|
||||||
|
static sd_dhcp_raw_option* raw_option_free(sd_dhcp_raw_option *i) {
|
||||||
|
if (!i)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
free(i->data);
|
||||||
|
return mfree(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
_public_ int sd_dhcp_raw_option_new(uint8_t type, char *data, size_t length, sd_dhcp_raw_option **ret) {
|
||||||
|
sd_dhcp_raw_option *p;
|
||||||
|
|
||||||
|
assert_return(ret, -EINVAL);
|
||||||
|
|
||||||
|
p = new(sd_dhcp_raw_option, 1);
|
||||||
|
if (!p)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
*p = (sd_dhcp_raw_option) {
|
||||||
|
.n_ref = 1,
|
||||||
|
.data = memdup(data, length),
|
||||||
|
.length = length,
|
||||||
|
.type = type,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!p->data)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
*ret = p;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_raw_option, sd_dhcp_raw_option, raw_option_free);
|
||||||
|
DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||||
|
dhcp_raw_options_hash_ops,
|
||||||
|
void,
|
||||||
|
trivial_hash_func,
|
||||||
|
trivial_compare_func,
|
||||||
|
sd_dhcp_raw_option,
|
||||||
|
sd_dhcp_raw_option_unref);
|
||||||
|
|
||||||
static sd_dhcp_server *dhcp_server_free(sd_dhcp_server *server) {
|
static sd_dhcp_server *dhcp_server_free(sd_dhcp_server *server) {
|
||||||
assert(server);
|
assert(server);
|
||||||
|
|
||||||
|
@ -143,6 +183,8 @@ static sd_dhcp_server *dhcp_server_free(sd_dhcp_server *server) {
|
||||||
|
|
||||||
hashmap_free(server->leases_by_client_id);
|
hashmap_free(server->leases_by_client_id);
|
||||||
|
|
||||||
|
ordered_hashmap_free(server->raw_option);
|
||||||
|
|
||||||
free(server->bound_leases);
|
free(server->bound_leases);
|
||||||
return mfree(server);
|
return mfree(server);
|
||||||
}
|
}
|
||||||
|
@ -452,8 +494,8 @@ static int server_send_offer(sd_dhcp_server *server, DHCPRequest *req,
|
||||||
static int server_send_ack(sd_dhcp_server *server, DHCPRequest *req,
|
static int server_send_ack(sd_dhcp_server *server, DHCPRequest *req,
|
||||||
be32_t address) {
|
be32_t address) {
|
||||||
_cleanup_free_ DHCPPacket *packet = NULL;
|
_cleanup_free_ DHCPPacket *packet = NULL;
|
||||||
size_t offset;
|
|
||||||
be32_t lease_time;
|
be32_t lease_time;
|
||||||
|
size_t offset;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = server_message_init(server, &packet, DHCP_ACK, &offset, req);
|
r = server_message_init(server, &packet, DHCP_ACK, &offset, req);
|
||||||
|
@ -517,6 +559,15 @@ static int server_send_ack(sd_dhcp_server *server, DHCPRequest *req,
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ordered_hashmap_isempty(server->raw_option)) {
|
||||||
|
r = dhcp_option_append(
|
||||||
|
&packet->dhcp, req->max_optlen, &offset, 0,
|
||||||
|
SD_DHCP_OPTION_VENDOR_SPECIFIC,
|
||||||
|
ordered_hashmap_size(server->raw_option), server->raw_option);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
r = dhcp_server_send_packet(server, req, packet, DHCP_ACK, offset);
|
r = dhcp_server_send_packet(server, req, packet, DHCP_ACK, offset);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
@ -1170,3 +1221,22 @@ int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled) {
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sd_dhcp_server_add_raw_option(sd_dhcp_server *server, sd_dhcp_raw_option *v) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert_return(server, -EINVAL);
|
||||||
|
assert_return(v, -EINVAL);
|
||||||
|
|
||||||
|
r = ordered_hashmap_ensure_allocated(&server->raw_option, &dhcp_raw_options_hash_ops);
|
||||||
|
if (r < 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
r = ordered_hashmap_put(server->raw_option, v, v);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
sd_dhcp_raw_option_ref(v);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
|
@ -2,11 +2,15 @@
|
||||||
|
|
||||||
#include "sd-dhcp-server.h"
|
#include "sd-dhcp-server.h"
|
||||||
|
|
||||||
|
#include "escape.h"
|
||||||
#include "networkd-dhcp-server.h"
|
#include "networkd-dhcp-server.h"
|
||||||
#include "networkd-link.h"
|
#include "networkd-link.h"
|
||||||
#include "networkd-manager.h"
|
#include "networkd-manager.h"
|
||||||
#include "networkd-network.h"
|
#include "networkd-network.h"
|
||||||
|
#include "parse-util.h"
|
||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
|
#include "string-table.h"
|
||||||
|
#include "string-util.h"
|
||||||
|
|
||||||
static Address* link_find_dhcp_server_address(Link *link) {
|
static Address* link_find_dhcp_server_address(Link *link) {
|
||||||
Address *address;
|
Address *address;
|
||||||
|
@ -187,9 +191,11 @@ static int link_push_uplink_sip_to_dhcp_server(Link *link, sd_dhcp_server *s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int dhcp4_server_configure(Link *link) {
|
int dhcp4_server_configure(Link *link) {
|
||||||
Address *address;
|
|
||||||
Link *uplink = NULL;
|
|
||||||
bool acquired_uplink = false;
|
bool acquired_uplink = false;
|
||||||
|
sd_dhcp_raw_option *p;
|
||||||
|
Link *uplink = NULL;
|
||||||
|
Address *address;
|
||||||
|
Iterator i;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
address = link_find_dhcp_server_address(link);
|
address = link_find_dhcp_server_address(link);
|
||||||
|
@ -298,6 +304,15 @@ int dhcp4_server_configure(Link *link) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ORDERED_HASHMAP_FOREACH(p, link->network->dhcp_server_raw_options, i) {
|
||||||
|
r = sd_dhcp_server_add_raw_option(link->dhcp_server, p);
|
||||||
|
if (r == -EEXIST)
|
||||||
|
continue;
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
if (!sd_dhcp_server_is_running(link->dhcp_server)) {
|
if (!sd_dhcp_server_is_running(link->dhcp_server)) {
|
||||||
r = sd_dhcp_server_start(link->dhcp_server);
|
r = sd_dhcp_server_start(link->dhcp_server);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -464,3 +479,178 @@ int config_parse_dhcp_server_sip(
|
||||||
n->dhcp_server_sip = m;
|
n->dhcp_server_sip = m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char * const dhcp_raw_option_data_type_table[_DHCP_RAW_OPTION_DATA_MAX] = {
|
||||||
|
[DHCP_RAW_OPTION_DATA_UINT8] = "uint8",
|
||||||
|
[DHCP_RAW_OPTION_DATA_UINT16] = "uint16",
|
||||||
|
[DHCP_RAW_OPTION_DATA_UINT32] = "uint32",
|
||||||
|
[DHCP_RAW_OPTION_DATA_STRING] = "string",
|
||||||
|
[DHCP_RAW_OPTION_DATA_IPV4ADDRESS] = "ipv4address",
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFINE_STRING_TABLE_LOOKUP(dhcp_raw_option_data_type, DHCPRawOption);
|
||||||
|
|
||||||
|
int config_parse_dhcp_server_raw_option_data(
|
||||||
|
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_raw_option_unrefp) sd_dhcp_raw_option *opt = NULL, *old = NULL;
|
||||||
|
_cleanup_free_ char *word = NULL, *q = NULL;
|
||||||
|
union in_addr_union addr;
|
||||||
|
Network *network = data;
|
||||||
|
uint16_t uint16_data;
|
||||||
|
uint32_t uint32_data;
|
||||||
|
uint8_t uint8_data;
|
||||||
|
DHCPRawOption type;
|
||||||
|
const char *p;
|
||||||
|
void *udata;
|
||||||
|
ssize_t sz;
|
||||||
|
uint8_t u;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(filename);
|
||||||
|
assert(lvalue);
|
||||||
|
assert(rvalue);
|
||||||
|
assert(data);
|
||||||
|
|
||||||
|
if (isempty(rvalue)) {
|
||||||
|
network->dhcp_server_raw_options = ordered_hashmap_free(network->dhcp_server_raw_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 server send raw option, ignoring assignment: %s", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = safe_atou8(word, &u);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
"Failed to parse DHCP server send raw option type, ignoring assignment: %s", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (u < 1 || u >= 255) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||||
|
"Invalid DHCP server send raw option, valid range is 1-254, ignoring assignment: %s", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(word);
|
||||||
|
|
||||||
|
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 server send raw option, ignoring assignment: %s", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = dhcp_raw_option_data_type_from_string(word);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
"Invalid DHCP server send data type, ignoring assignment: %s", p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
type = r;
|
||||||
|
switch(type) {
|
||||||
|
case DHCP_RAW_OPTION_DATA_UINT8:{
|
||||||
|
r = safe_atou8(p, &uint8_data);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
"Failed to parse DHCPv4 vendor specific uint8 data, ignoring assignment: %s", p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
udata = &uint8_data;
|
||||||
|
sz = sizeof(uint8_t);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DHCP_RAW_OPTION_DATA_UINT16:{
|
||||||
|
r = safe_atou16(p, &uint16_data);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
"Failed to parse DHCPv4 vendor specific uint16 data, ignoring assignment: %s", p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
udata = &uint16_data;
|
||||||
|
sz = sizeof(uint16_t);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DHCP_RAW_OPTION_DATA_UINT32: {
|
||||||
|
r = safe_atou32(p, &uint32_data);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
"Failed to parse DHCPv4 vendor specific uint32 data, ignoring assignment: %s", p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
udata = &uint32_data;
|
||||||
|
sz = sizeof(uint32_t);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DHCP_RAW_OPTION_DATA_IPV4ADDRESS: {
|
||||||
|
r = in_addr_from_string(AF_INET, p, &addr);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
"Failed to parse DHCPv4 vendor specific ipv4address data, ignoring assignment: %s", p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
udata = &addr.in;
|
||||||
|
sz = sizeof(addr.in.s_addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DHCP_RAW_OPTION_DATA_STRING:
|
||||||
|
sz = cunescape(p, 0, &q);
|
||||||
|
if (sz < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, sz,
|
||||||
|
"Failed to decode option data, ignoring assignment: %s", p);
|
||||||
|
}
|
||||||
|
|
||||||
|
udata = q;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_dhcp_raw_option_new(u, udata, sz, &opt);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
"Failed to store DHCP send raw option '%s', ignoring assignment: %m", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = ordered_hashmap_ensure_allocated(&network->dhcp_server_raw_options, &dhcp_raw_options_hash_ops);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
/* Overwrite existing option */
|
||||||
|
old = ordered_hashmap_remove(network->dhcp_server_raw_options, UINT_TO_PTR(u));
|
||||||
|
r = ordered_hashmap_put(network->dhcp_server_raw_options, UINT_TO_PTR(u), opt);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
"Failed to store DHCP server send raw option '%s'", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAKE_PTR(opt);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -2,11 +2,27 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "conf-parser.h"
|
#include "conf-parser.h"
|
||||||
|
#include "networkd-link.h"
|
||||||
|
#include "networkd-util.h"
|
||||||
|
|
||||||
typedef struct Link Link;
|
typedef struct Link Link;
|
||||||
|
|
||||||
|
typedef enum DHCPRawOption {
|
||||||
|
DHCP_RAW_OPTION_DATA_UINT8,
|
||||||
|
DHCP_RAW_OPTION_DATA_UINT16,
|
||||||
|
DHCP_RAW_OPTION_DATA_UINT32,
|
||||||
|
DHCP_RAW_OPTION_DATA_STRING,
|
||||||
|
DHCP_RAW_OPTION_DATA_IPV4ADDRESS,
|
||||||
|
_DHCP_RAW_OPTION_DATA_MAX,
|
||||||
|
_DHCP_RAW_OPTION_DATA_INVALID,
|
||||||
|
} DHCPRawOption;
|
||||||
|
|
||||||
|
const char *dhcp_raw_option_data_type_to_string(DHCPRawOption d) _const_;
|
||||||
|
DHCPRawOption dhcp_raw_option_data_type_from_string(const char *d) _pure_;
|
||||||
|
|
||||||
int dhcp4_server_configure(Link *link);
|
int dhcp4_server_configure(Link *link);
|
||||||
|
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_dns);
|
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_dns);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_ntp);
|
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_ntp);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_sip);
|
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_sip);
|
||||||
|
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_raw_option_data);
|
||||||
|
|
|
@ -200,6 +200,7 @@ DHCPServer.EmitTimezone, config_parse_bool,
|
||||||
DHCPServer.Timezone, config_parse_timezone, 0, offsetof(Network, dhcp_server_timezone)
|
DHCPServer.Timezone, config_parse_timezone, 0, offsetof(Network, dhcp_server_timezone)
|
||||||
DHCPServer.PoolOffset, config_parse_uint32, 0, offsetof(Network, dhcp_server_pool_offset)
|
DHCPServer.PoolOffset, config_parse_uint32, 0, offsetof(Network, dhcp_server_pool_offset)
|
||||||
DHCPServer.PoolSize, config_parse_uint32, 0, offsetof(Network, dhcp_server_pool_size)
|
DHCPServer.PoolSize, config_parse_uint32, 0, offsetof(Network, dhcp_server_pool_size)
|
||||||
|
DHCPServer.SendRawOption, config_parse_dhcp_server_raw_option_data, 0, 0
|
||||||
Bridge.Cost, config_parse_uint32, 0, offsetof(Network, cost)
|
Bridge.Cost, config_parse_uint32, 0, offsetof(Network, cost)
|
||||||
Bridge.UseBPDU, config_parse_tristate, 0, offsetof(Network, use_bpdu)
|
Bridge.UseBPDU, config_parse_tristate, 0, offsetof(Network, use_bpdu)
|
||||||
Bridge.HairPin, config_parse_tristate, 0, offsetof(Network, hairpin)
|
Bridge.HairPin, config_parse_tristate, 0, offsetof(Network, hairpin)
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "hostname-util.h"
|
#include "hostname-util.h"
|
||||||
#include "in-addr-util.h"
|
#include "in-addr-util.h"
|
||||||
|
#include "networkd-dhcp-server.h"
|
||||||
#include "network-internal.h"
|
#include "network-internal.h"
|
||||||
#include "networkd-manager.h"
|
#include "networkd-manager.h"
|
||||||
#include "networkd-network.h"
|
#include "networkd-network.h"
|
||||||
|
@ -144,14 +145,14 @@ static int network_resolve_stacked_netdevs(Network *network) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int network_verify(Network *network) {
|
int network_verify(Network *network) {
|
||||||
Address *address, *address_next;
|
RoutingPolicyRule *rule, *rule_next;
|
||||||
Route *route, *route_next;
|
|
||||||
FdbEntry *fdb, *fdb_next;
|
|
||||||
Neighbor *neighbor, *neighbor_next;
|
Neighbor *neighbor, *neighbor_next;
|
||||||
AddressLabel *label, *label_next;
|
AddressLabel *label, *label_next;
|
||||||
Prefix *prefix, *prefix_next;
|
|
||||||
RoutingPolicyRule *rule, *rule_next;
|
|
||||||
NextHop *nexthop, *nextnop_next;
|
NextHop *nexthop, *nextnop_next;
|
||||||
|
Address *address, *address_next;
|
||||||
|
Prefix *prefix, *prefix_next;
|
||||||
|
Route *route, *route_next;
|
||||||
|
FdbEntry *fdb, *fdb_next;
|
||||||
|
|
||||||
assert(network);
|
assert(network);
|
||||||
assert(network->filename);
|
assert(network->filename);
|
||||||
|
@ -680,6 +681,7 @@ static Network *network_free(Network *network) {
|
||||||
set_free_free(network->dnssec_negative_trust_anchors);
|
set_free_free(network->dnssec_negative_trust_anchors);
|
||||||
|
|
||||||
ordered_hashmap_free(network->dhcp_send_options);
|
ordered_hashmap_free(network->dhcp_send_options);
|
||||||
|
ordered_hashmap_free(network->dhcp_server_raw_options);
|
||||||
|
|
||||||
return mfree(network);
|
return mfree(network);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "networkd-brvlan.h"
|
#include "networkd-brvlan.h"
|
||||||
#include "networkd-dhcp-common.h"
|
#include "networkd-dhcp-common.h"
|
||||||
#include "networkd-dhcp4.h"
|
#include "networkd-dhcp4.h"
|
||||||
|
#include "networkd-dhcp-server.h"
|
||||||
#include "networkd-fdb.h"
|
#include "networkd-fdb.h"
|
||||||
#include "networkd-ipv6-proxy-ndp.h"
|
#include "networkd-ipv6-proxy-ndp.h"
|
||||||
#include "networkd-lldp-rx.h"
|
#include "networkd-lldp-rx.h"
|
||||||
|
@ -114,6 +115,7 @@ struct Network {
|
||||||
Set *dhcp_black_listed_ip;
|
Set *dhcp_black_listed_ip;
|
||||||
Set *dhcp_request_options;
|
Set *dhcp_request_options;
|
||||||
OrderedHashmap *dhcp_send_options;
|
OrderedHashmap *dhcp_send_options;
|
||||||
|
OrderedHashmap *dhcp_server_raw_options;
|
||||||
|
|
||||||
/* DHCPv6 Client support*/
|
/* DHCPv6 Client support*/
|
||||||
bool dhcp6_use_dns;
|
bool dhcp6_use_dns;
|
||||||
|
|
|
@ -27,13 +27,20 @@
|
||||||
|
|
||||||
_SD_BEGIN_DECLARATIONS;
|
_SD_BEGIN_DECLARATIONS;
|
||||||
|
|
||||||
|
extern const struct hash_ops dhcp_raw_options_hash_ops;
|
||||||
|
|
||||||
typedef struct sd_dhcp_server sd_dhcp_server;
|
typedef struct sd_dhcp_server sd_dhcp_server;
|
||||||
|
typedef struct sd_dhcp_raw_option sd_dhcp_raw_option;
|
||||||
|
|
||||||
int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex);
|
int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex);
|
||||||
|
|
||||||
sd_dhcp_server *sd_dhcp_server_ref(sd_dhcp_server *server);
|
sd_dhcp_server *sd_dhcp_server_ref(sd_dhcp_server *server);
|
||||||
sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server);
|
sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server);
|
||||||
|
|
||||||
|
int sd_dhcp_raw_option_new(uint8_t type, char *data, size_t lengt, sd_dhcp_raw_option **ret);
|
||||||
|
sd_dhcp_raw_option *sd_dhcp_raw_option_ref(sd_dhcp_raw_option *ra);
|
||||||
|
sd_dhcp_raw_option *sd_dhcp_raw_option_unref(sd_dhcp_raw_option *ra);
|
||||||
|
|
||||||
int sd_dhcp_server_attach_event(sd_dhcp_server *client, sd_event *event, int64_t priority);
|
int sd_dhcp_server_attach_event(sd_dhcp_server *client, sd_event *event, int64_t priority);
|
||||||
int sd_dhcp_server_detach_event(sd_dhcp_server *client);
|
int sd_dhcp_server_detach_event(sd_dhcp_server *client);
|
||||||
sd_event *sd_dhcp_server_get_event(sd_dhcp_server *client);
|
sd_event *sd_dhcp_server_get_event(sd_dhcp_server *client);
|
||||||
|
@ -51,12 +58,15 @@ int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], u
|
||||||
int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], unsigned n);
|
int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], unsigned n);
|
||||||
int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled);
|
int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled);
|
||||||
|
|
||||||
|
int sd_dhcp_server_add_raw_option(sd_dhcp_server *server, sd_dhcp_raw_option *v);
|
||||||
|
|
||||||
int sd_dhcp_server_set_max_lease_time(sd_dhcp_server *server, uint32_t t);
|
int sd_dhcp_server_set_max_lease_time(sd_dhcp_server *server, uint32_t t);
|
||||||
int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t);
|
int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t);
|
||||||
|
|
||||||
int sd_dhcp_server_forcerenew(sd_dhcp_server *server);
|
int sd_dhcp_server_forcerenew(sd_dhcp_server *server);
|
||||||
|
|
||||||
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_server, sd_dhcp_server_unref);
|
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_server, sd_dhcp_server_unref);
|
||||||
|
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_raw_option, sd_dhcp_raw_option_unref);
|
||||||
|
|
||||||
_SD_END_DECLARATIONS;
|
_SD_END_DECLARATIONS;
|
||||||
|
|
||||||
|
|
|
@ -259,6 +259,7 @@ MaxLeaseTimeSec=
|
||||||
DefaultLeaseTimeSec=
|
DefaultLeaseTimeSec=
|
||||||
EmitTimezone=
|
EmitTimezone=
|
||||||
DNS=
|
DNS=
|
||||||
|
SendRawOption=
|
||||||
[NextHop]
|
[NextHop]
|
||||||
Id=
|
Id=
|
||||||
Gateway=
|
Gateway=
|
||||||
|
|
Loading…
Reference in New Issue