/* SPDX-License-Identifier: LGPL-2.1+ */
#include "dhcp-internal.h"
+#include "dhcp6-internal.h"
#include "escape.h"
#include "in-addr-util.h"
#include "networkd-dhcp-common.h"
void *data,
void *userdata) {
- _cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt = NULL, *old = NULL;
+ _cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt4 = NULL, *old4 = NULL;
+ _cleanup_(sd_dhcp6_option_unrefp) sd_dhcp6_option *opt6 = NULL, *old6 = NULL;
_cleanup_free_ char *word = NULL, *q = NULL;
OrderedHashmap **options = data;
union in_addr_union addr;
DHCPOptionDataType type;
- uint8_t u, uint8_data;
- uint16_t uint16_data;
+ uint8_t u8, uint8_data;
+ uint16_t u16, uint16_data;
uint32_t uint32_data;
const void *udata;
const char *p;
return 0;
}
- r = safe_atou8(word, &u);
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r,
- "Invalid DHCP option, ignoring assignment: %s", rvalue);
- return 0;
- }
- if (u < 1 || u >= 255) {
- log_syntax(unit, LOG_ERR, filename, line, 0,
- "Invalid DHCP option, valid range is 1-254, ignoring assignment: %s", rvalue);
- return 0;
+ if (ltype == AF_INET6) {
+ r = safe_atou16(word, &u16);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Invalid DHCP option, ignoring assignment: %s", rvalue);
+ return 0;
+ }
+ if (u16 < 1 || u16 >= 65535) {
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Invalid DHCP option, valid range is 1-65535, ignoring assignment: %s", rvalue);
+ return 0;
+ }
+ } else {
+ r = safe_atou8(word, &u8);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Invalid DHCP option, ignoring assignment: %s", rvalue);
+ return 0;
+ }
+ if (u8 < 1 || u8 >= 255) {
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Invalid DHCP option, valid range is 1-254, ignoring assignment: %s", rvalue);
+ return 0;
+ }
}
word = mfree(word);
r = safe_atou8(p, &uint8_data);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
- "Failed to parse DHCPv4 uint8 data, ignoring assignment: %s", p);
+ "Failed to parse DHCP uint8 data, ignoring assignment: %s", p);
return 0;
}
r = safe_atou16(p, &uint16_data);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
- "Failed to parse DHCPv4 uint16 data, ignoring assignment: %s", p);
+ "Failed to parse DHCP uint16 data, ignoring assignment: %s", p);
return 0;
}
r = safe_atou32(p, &uint32_data);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
- "Failed to parse DHCPv4 uint32 data, ignoring assignment: %s", p);
+ "Failed to parse DHCP uint32 data, ignoring assignment: %s", p);
return 0;
}
r = in_addr_from_string(AF_INET, p, &addr);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
- "Failed to parse DHCPv4 ipv4address data, ignoring assignment: %s", p);
+ "Failed to parse DHCP ipv4address data, ignoring assignment: %s", p);
return 0;
}
sz = sizeof(addr.in.s_addr);
break;
}
+ case DHCP_OPTION_DATA_IPV6ADDRESS: {
+ r = in_addr_from_string(AF_INET6, p, &addr);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to parse DHCP ipv6address data, ignoring assignment: %s", p);
+ return 0;
+ }
+
+ udata = &addr.in6;
+ sz = sizeof(addr.in6.s6_addr);
+ break;
+ }
case DHCP_OPTION_DATA_STRING:
sz = cunescape(p, UNESCAPE_ACCEPT_NUL, &q);
if (sz < 0) {
log_syntax(unit, LOG_ERR, filename, line, sz,
- "Failed to decode DHCPv4 option data, ignoring assignment: %s", p);
+ "Failed to decode DHCP option data, ignoring assignment: %s", p);
}
udata = q;
return -EINVAL;
}
- r = sd_dhcp_option_new(u, udata, sz, &opt);
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r,
- "Failed to store DHCPv4 option '%s', ignoring assignment: %m", rvalue);
- return 0;
- }
+ if (ltype == AF_INET6) {
+ r = sd_dhcp6_option_new(u16, udata, sz, &opt6);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to store DHCP option '%s', ignoring assignment: %m", rvalue);
+ return 0;
+ }
- r = ordered_hashmap_ensure_allocated(options, &dhcp_option_hash_ops);
- if (r < 0)
- return log_oom();
+ r = ordered_hashmap_ensure_allocated(options, &dhcp6_option_hash_ops);
+ if (r < 0)
+ return log_oom();
- /* Overwrite existing option */
- old = ordered_hashmap_remove(*options, UINT_TO_PTR(u));
- r = ordered_hashmap_put(*options, UINT_TO_PTR(u), opt);
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r,
- "Failed to store DHCPv4 option '%s', ignoring assignment: %m", rvalue);
- return 0;
- }
+ /* Overwrite existing option */
+ old6 = ordered_hashmap_get(*options, UINT_TO_PTR(u16));
+ r = ordered_hashmap_replace(*options, UINT_TO_PTR(u16), opt6);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to store DHCP option '%s', ignoring assignment: %m", rvalue);
+ return 0;
+ }
+ TAKE_PTR(opt6);
+ } else {
+ r = sd_dhcp_option_new(u8, udata, sz, &opt4);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to store DHCP option '%s', ignoring assignment: %m", rvalue);
+ return 0;
+ }
- TAKE_PTR(opt);
+ r = ordered_hashmap_ensure_allocated(options, &dhcp_option_hash_ops);
+ if (r < 0)
+ return log_oom();
+
+ /* Overwrite existing option */
+ old4 = ordered_hashmap_get(*options, UINT_TO_PTR(u8));
+ r = ordered_hashmap_replace(*options, UINT_TO_PTR(u8), opt4);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to store DHCP option '%s', ignoring assignment: %m", rvalue);
+ return 0;
+ }
+ TAKE_PTR(opt4);
+ }
return 0;
}
[DHCP_OPTION_DATA_UINT32] = "uint32",
[DHCP_OPTION_DATA_STRING] = "string",
[DHCP_OPTION_DATA_IPV4ADDRESS] = "ipv4address",
+ [DHCP_OPTION_DATA_IPV6ADDRESS] = "ipv6address",
};
DEFINE_STRING_TABLE_LOOKUP(dhcp_option_data_type, DHCPOptionDataType);
DHCPv4.SendDecline, config_parse_bool, 0, offsetof(Network, dhcp_send_decline)
DHCPv4.BlackList, config_parse_dhcp_black_listed_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, 0, offsetof(Network, dhcp_client_send_options)
+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)
DHCPv4.RouteMTUBytes, config_parse_mtu, AF_INET, offsetof(Network, dhcp_route_mtu)
DHCPv6.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp6_use_dns)
DHCPv6.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information)
DHCPv6.PrefixDelegationHint, config_parse_dhcp6_pd_hint, 0, 0
DHCPv6.WithoutRA, config_parse_bool, 0, offsetof(Network, dhcp6_without_ra)
+DHCPv6.SendOption, config_parse_dhcp_send_option, AF_INET6, offsetof(Network, dhcp6_client_send_options)
IPv6AcceptRA.UseAutonomousPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_autonomous_prefix)
IPv6AcceptRA.UseOnLinkPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_onlink_prefix)
IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns)