summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/systemd.network.xml8
-rw-r--r--network/80-container-host0.network3
-rw-r--r--src/network/networkd-link.c67
-rw-r--r--src/network/networkd-network-gperf.gperf9
-rw-r--r--src/network/networkd.h21
5 files changed, 92 insertions, 16 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 5bff4d9d8..67f10e1ef 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -195,7 +195,9 @@
<varlistentry>
<term><varname>DHCP=</varname></term>
<listitem>
- <para>A boolean. When true, enables basic DHCPv4 support.</para>
+ <para>Enables DHCPv4 and/or DHCPv6 support. Accepts
+ <literal>both</literal>, <literal>none</literal>,
+ <literal>v4</literal> or <literal>v6</literal>.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -361,8 +363,8 @@
</refsect1>
<refsect1>
- <title>[DHCPv4] Section Options</title>
- <para>The <literal>[DHCPv4]</literal> section accepts the following keys:</para>
+ <title>[DHCP] Section Options</title>
+ <para>The <literal>[DHCP]</literal> section accepts the following keys:</para>
<variablelist class='network-directives'>
<varlistentry>
diff --git a/network/80-container-host0.network b/network/80-container-host0.network
index 76c0f1db4..6863ca9ce 100644
--- a/network/80-container-host0.network
+++ b/network/80-container-host0.network
@@ -10,6 +10,5 @@ Virtualization=container
Name=host0
[Network]
-DHCP=yes
-DHCPv6=yes
+DHCP=both
IPv4LL=yes
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 6bff73d42..5d280b5b8 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -29,6 +29,7 @@
#include "virt.h"
#include "bus-util.h"
#include "network-internal.h"
+#include "conf-parser.h"
#include "network-util.h"
#include "dhcp-lease-internal.h"
@@ -205,7 +206,7 @@ static int link_stop_clients(Link *link) {
if (!link->network)
return 0;
- if (link->network->dhcp) {
+ if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
assert(link->dhcp_client);
k = sd_dhcp_client_stop(link->dhcp_client);
@@ -235,7 +236,7 @@ static int link_stop_clients(Link *link) {
}
}
- if (link->network->dhcp6) {
+ if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
assert(link->icmp6_router_discovery);
if (link->dhcp6_client) {
@@ -1456,7 +1457,7 @@ static int link_acquire_conf(Link *link) {
}
}
- if (link->network->dhcp) {
+ if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
assert(link->dhcp_client);
log_debug_link(link, "acquiring DHCPv4 lease");
@@ -1469,7 +1470,7 @@ static int link_acquire_conf(Link *link) {
}
}
- if (link->network->dhcp6) {
+ if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
assert(link->icmp6_router_discovery);
log_debug_link(link, "discovering IPv6 routers");
@@ -1682,7 +1683,7 @@ static int link_enslaved(Link *link) {
}
}
- if (!link->network->dhcp && !link->network->ipv4ll)
+ if ((link->network->dhcp == DHCP_SUPPORT_NONE) && !link->network->ipv4ll)
return link_enter_set_addresses(link);
return 0;
@@ -1925,7 +1926,7 @@ static int link_configure(Link *link) {
return r;
}
- if (link->network->dhcp) {
+ if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
r = sd_dhcp_client_new(&link->dhcp_client);
if (r < 0)
return r;
@@ -1963,7 +1964,7 @@ static int link_configure(Link *link) {
return r;
}
- if (link->network->dhcp6) {
+ if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
r = sd_icmp6_nd_new(&link->icmp6_router_discovery);
if (r < 0)
return r;
@@ -2496,3 +2497,55 @@ static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
};
DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);
+
+static const char* const dhcp_support_table[_DHCP_SUPPORT_MAX] = {
+ [DHCP_SUPPORT_NONE] = "none",
+ [DHCP_SUPPORT_BOTH] = "both",
+ [DHCP_SUPPORT_V4] = "v4",
+ [DHCP_SUPPORT_V6] = "v6",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(dhcp_support, DHCPSupport);
+
+int config_parse_dhcp(
+ 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) {
+
+ DHCPSupport *dhcp = data;
+ int k;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ /* Our enum shall be a superset of booleans, hence first try
+ * to parse as boolean, and then as enum */
+
+ k = parse_boolean(rvalue);
+ if (k > 0)
+ *dhcp = DHCP_SUPPORT_BOTH;
+ else if (k == 0)
+ *dhcp = DHCP_SUPPORT_NONE;
+ else {
+ DHCPSupport s;
+
+ s = dhcp_support_from_string(rvalue);
+ if (s < 0){
+ log_syntax(unit, LOG_ERR, filename, line, -s, "Failed to parse DHCP option, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ *dhcp = s;
+ }
+
+ return 0;
+}
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 469e02868..c8610d14f 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -30,10 +30,9 @@ Network.Bond, config_parse_netdev, 0,
Network.VLAN, config_parse_netdev, 0, offsetof(Network, vlans)
Network.MACVLAN, config_parse_netdev, 0, offsetof(Network, macvlans)
Network.VXLAN, config_parse_netdev, 0, offsetof(Network, vxlans)
-Network.DHCP, config_parse_bool, 0, offsetof(Network, dhcp)
+Network.DHCP, config_parse_dhcp, 0, offsetof(Network, dhcp)
Network.DHCPServer, config_parse_bool, 0, offsetof(Network, dhcp_server)
Network.IPv4LL, config_parse_bool, 0, offsetof(Network, ipv4ll)
-Network.DHCPv6, config_parse_bool, 0, offsetof(Network, dhcp6)
Network.Address, config_parse_address, 0, 0
Network.Gateway, config_parse_gateway, 0, 0
Network.DNS, config_parse_dns, 0, offsetof(Network, dns)
@@ -44,6 +43,12 @@ Address.Broadcast, config_parse_broadcast, 0,
Address.Label, config_parse_label, 0, 0
Route.Gateway, config_parse_gateway, 0, 0
Route.Destination, config_parse_destination, 0, 0
+DHCP.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_dns)
+DHCP.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_mtu)
+DHCP.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_hostname)
+DHCP.UseDomainName, config_parse_bool, 0, offsetof(Network, dhcp_domainname)
+DHCP.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical)
+/* backwards compatibility */
DHCPv4.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_dns)
DHCPv4.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_mtu)
DHCPv4.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_hostname)
diff --git a/src/network/networkd.h b/src/network/networkd.h
index b7b1d903b..67f70d9e6 100644
--- a/src/network/networkd.h
+++ b/src/network/networkd.h
@@ -131,6 +131,15 @@ struct NetDev {
LIST_HEAD(netdev_enslave_callback, callbacks);
};
+typedef enum DHCPSupport {
+ DHCP_SUPPORT_NONE,
+ DHCP_SUPPORT_BOTH,
+ DHCP_SUPPORT_V4,
+ DHCP_SUPPORT_V6,
+ _DHCP_SUPPORT_MAX,
+ _DHCP_SUPPORT_INVALID = -1,
+} DHCPSupport;
+
struct Network {
Manager *manager;
@@ -153,7 +162,7 @@ struct Network {
Hashmap *vlans;
Hashmap *macvlans;
Hashmap *vxlans;
- bool dhcp;
+ DHCPSupport dhcp;
bool dhcp_dns;
bool dhcp_ntp;
bool dhcp_mtu;
@@ -161,7 +170,6 @@ struct Network {
bool dhcp_domainname;
bool dhcp_critical;
bool ipv4ll;
- bool dhcp6;
bool dhcp_server;
@@ -472,6 +480,15 @@ LinkOperationalState link_operstate_from_string(const char *s) _pure_;
DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_unref);
#define _cleanup_link_unref_ _cleanup_(link_unrefp)
+/* DHCP support */
+
+const char* dhcp_support_to_string(DHCPSupport i) _const_;
+DHCPSupport dhcp_support_from_string(const char *s) _pure_;
+
+int config_parse_dhcp(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);
+
/* Address Pool */
int address_pool_new(Manager *m, AddressPool **ret, unsigned family, const union in_addr_union *u, unsigned prefixlen);