summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--man/systemd.network.xml10
-rw-r--r--src/network/networkd-dhcp4.c64
-rw-r--r--src/network/networkd-dhcp4.h2
-rw-r--r--src/network/networkd-network-gperf.gperf5
-rw-r--r--src/network/networkd-network.c1
-rw-r--r--src/network/networkd-network.h1
-rw-r--r--test/fuzz/fuzz-network-parser/directives.network1
7 files changed, 67 insertions, 17 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 88f00bdca6..d08543c5fc 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -1748,7 +1748,15 @@
<varlistentry>
<term><varname>DenyList=</varname></term>
<listitem>
- <para>A whitespace-separated list of IPv4 addresses. DHCP offers from servers in the list are rejected.</para>
+ <para>A whitespace-separated list of IPv4 addresses. DHCP offers from servers in the list are rejected. Note that
+ if <varname>AllowList=</varname> is configured then <varname>DenyList=</varname> is ignored.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>AllowList=</varname></term>
+ <listitem>
+ <para>A whitespace-separated list of IPv4 addresses. DHCP offers from servers in the list are accepted.</para>
</listitem>
</varlistentry>
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
index 20dae6c19f..9a99c1e6f9 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -1079,6 +1079,34 @@ static int dhcp_server_is_deny_listed(Link *link, sd_dhcp_client *client) {
return false;
}
+static int dhcp_server_is_allow_listed(Link *link, sd_dhcp_client *client) {
+ sd_dhcp_lease *lease;
+ struct in_addr addr;
+ int r;
+
+ assert(link);
+ assert(link->network);
+ assert(client);
+
+ r = sd_dhcp_client_get_lease(client, &lease);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Failed to get DHCP lease: %m");
+
+ r = sd_dhcp_lease_get_server_identifier(lease, &addr);
+ if (r < 0)
+ return log_link_debug_errno(link, r, "Failed to get DHCP server ip address: %m");
+
+ if (set_contains(link->network->dhcp_allow_listed_ip, UINT32_TO_PTR(addr.s_addr))) {
+ log_struct(LOG_DEBUG,
+ LOG_LINK_INTERFACE(link),
+ LOG_LINK_MESSAGE(link, "DHCPv4 ip '%u.%u.%u.%u' found in allow-listed ip addresses, accepting offer",
+ ADDRESS_FMT_VAL(addr)));
+ return true;
+ }
+
+ return false;
+}
+
static int dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
Link *link = userdata;
int r;
@@ -1163,12 +1191,19 @@ static int dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
}
break;
case SD_DHCP_CLIENT_EVENT_SELECTING:
- r = dhcp_server_is_deny_listed(link, client);
- if (r < 0)
- return r;
- if (r != 0)
- return -ENOMSG;
-
+ if (!set_isempty(link->network->dhcp_allow_listed_ip)) {
+ r = dhcp_server_is_allow_listed(link, client);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return -ENOMSG;
+ } else {
+ r = dhcp_server_is_deny_listed(link, client);
+ if (r < 0)
+ return r;
+ if (r != 0)
+ return -ENOMSG;
+ }
break;
default:
if (event < 0)
@@ -1551,7 +1586,7 @@ int config_parse_dhcp_max_attempts(
return 0;
}
-int config_parse_dhcp_deny_listed_ip_address(
+int config_parse_dhcp_acl_ip_address(
const char *unit,
const char *filename,
unsigned line,
@@ -1564,6 +1599,7 @@ int config_parse_dhcp_deny_listed_ip_address(
void *userdata) {
Network *network = data;
+ Set **acl;
int r;
assert(filename);
@@ -1571,8 +1607,10 @@ int config_parse_dhcp_deny_listed_ip_address(
assert(rvalue);
assert(data);
+ acl = STR_IN_SET(lvalue, "DenyList", "BlackList") ? &network->dhcp_deny_listed_ip : &network->dhcp_allow_listed_ip;
+
if (isempty(rvalue)) {
- network->dhcp_deny_listed_ip = set_free(network->dhcp_deny_listed_ip);
+ *acl = set_free(*acl);
return 0;
}
@@ -1583,8 +1621,8 @@ int config_parse_dhcp_deny_listed_ip_address(
r = extract_first_word(&p, &n, NULL, 0);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
- "Failed to parse DHCP deny-listed IP address, ignoring assignment: %s",
- rvalue);
+ "Failed to parse DHCP '%s=' IP address, ignoring assignment: %s",
+ lvalue, rvalue);
return 0;
}
if (r == 0)
@@ -1593,14 +1631,14 @@ int config_parse_dhcp_deny_listed_ip_address(
r = in_addr_from_string(AF_INET, n, &ip);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
- "DHCP deny-listed IP address is invalid, ignoring assignment: %s", n);
+ "DHCP '%s=' IP address is invalid, ignoring assignment: %s", lvalue, n);
continue;
}
- r = set_ensure_put(&network->dhcp_deny_listed_ip, NULL, UINT32_TO_PTR(ip.in.s_addr));
+ r = set_ensure_put(acl, NULL, UINT32_TO_PTR(ip.in.s_addr));
if (r < 0)
log_syntax(unit, LOG_ERR, filename, line, r,
- "Failed to store DHCP deny-listed IP address '%s', ignoring assignment: %m", n);
+ "Failed to store DHCP '%s=' IP address '%s', ignoring assignment: %m", lvalue, n);
}
return 0;
diff --git a/src/network/networkd-dhcp4.h b/src/network/networkd-dhcp4.h
index 567ee724da..96ac696ce6 100644
--- a/src/network/networkd-dhcp4.h
+++ b/src/network/networkd-dhcp4.h
@@ -23,7 +23,7 @@ int dhcp4_set_client_identifier(Link *link);
int dhcp4_set_promote_secondaries(Link *link);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_client_identifier);
-CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_deny_listed_ip_address);
+CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_acl_ip_address);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_max_attempts);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_ip_service_type);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_mud_url);
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 087358da11..6b471c51e9 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -197,8 +197,8 @@ DHCPv4.IAID, config_parse_iaid,
DHCPv4.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port)
DHCPv4.SendRelease, config_parse_bool, 0, offsetof(Network, dhcp_send_release)
DHCPv4.SendDecline, config_parse_bool, 0, offsetof(Network, dhcp_send_decline)
-DHCPv4.DenyList, config_parse_dhcp_deny_listed_ip_address, 0, 0
-DHCPv4.BlackList, config_parse_dhcp_deny_listed_ip_address, 0, 0
+DHCPv4.DenyList, config_parse_dhcp_acl_ip_address, 0, 0
+DHCPv4.AllowList, config_parse_dhcp_acl_ip_address, 0, 0
DHCPv4.IPServiceType, config_parse_dhcp_ip_service_type, 0, offsetof(Network, ip_service_type)
DHCPv4.SendOption, config_parse_dhcp_send_option, AF_INET, offsetof(Network, dhcp_client_send_options)
DHCPv4.SendVendorOption, config_parse_dhcp_send_option, 0, offsetof(Network, dhcp_client_send_vendor_options)
@@ -414,6 +414,7 @@ TrivialLinkEqualizer.Handle, config_parse_qdisc_handle,
TrivialLinkEqualizer.Id, config_parse_trivial_link_equalizer_id, QDISC_KIND_TEQL, 0
/* backwards compatibility: do not add new entries to this section */
Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local)
+DHCPv4.BlackList, config_parse_dhcp_acl_ip_address, 0, 0
DHCP.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier)
DHCP.UseDNS, config_parse_dhcp_use_dns, 0, 0
DHCP.UseNTP, config_parse_dhcp_use_ntp, 0, 0
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 5316faeedb..22bd06a891 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -670,6 +670,7 @@ static Network *network_free(Network *network) {
strv_free(network->dhcp_user_class);
free(network->dhcp_hostname);
set_free(network->dhcp_deny_listed_ip);
+ set_free(network->dhcp_allow_listed_ip);
set_free(network->dhcp_request_options);
set_free(network->dhcp6_request_options);
free(network->mac);
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index 2ce555bfc5..424298248f 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -140,6 +140,7 @@ struct Network {
DHCPUseDomains dhcp_use_domains;
sd_ipv4acd *dhcp_acd;
Set *dhcp_deny_listed_ip;
+ Set *dhcp_allow_listed_ip;
Set *dhcp_request_options;
OrderedHashmap *dhcp_client_send_options;
OrderedHashmap *dhcp_client_send_vendor_options;
diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network
index 1754a1cd82..aa04c1192a 100644
--- a/test/fuzz/fuzz-network-parser/directives.network
+++ b/test/fuzz/fuzz-network-parser/directives.network
@@ -107,6 +107,7 @@ UseTimezone=
RouteTable=
DenyList=
BlackList=
+AllowList=
RequestOptions=
SendRelease=
MaxAttempts=