<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>
</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>
Name=host0
[Network]
-DHCP=yes
-DHCPv6=yes
+DHCP=both
IPv4LL=yes
#include "virt.h"
#include "bus-util.h"
#include "network-internal.h"
+#include "conf-parser.h"
#include "network-util.h"
#include "dhcp-lease-internal.h"
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);
}
}
- 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) {
}
}
- 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");
}
}
- 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");
}
}
- 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;
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;
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;
};
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;
+}
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)
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)
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;
Hashmap *vlans;
Hashmap *macvlans;
Hashmap *vxlans;
- bool dhcp;
+ DHCPSupport dhcp;
bool dhcp_dns;
bool dhcp_ntp;
bool dhcp_mtu;
bool dhcp_domainname;
bool dhcp_critical;
bool ipv4ll;
- bool dhcp6;
bool dhcp_server;
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);