#include <linux/if_arp.h>
#include "bus-error.h"
+#include "bus-locator.h"
#include "dhcp-identifier.h"
#include "dhcp-internal.h"
#include "dhcp6-internal.h"
return link_get_vrf_table(link);
}
-uint32_t link_get_dhcp6_route_table(Link *link) {
- assert(link);
- assert(link->network);
-
- if (link->network->dhcp6_route_table_set)
- return link->network->dhcp6_route_table;
- return link_get_vrf_table(link);
-}
-
uint32_t link_get_ipv6_accept_ra_route_table(Link *link) {
assert(link);
assert(link->network);
assert(link);
assert(IN_SET(family, AF_INET, AF_INET6));
+ /* Currently, sd-dhcp-client supports only ethernet and infiniband. */
+ if (family == AF_INET && !IN_SET(link->iftype, ARPHRD_ETHER, ARPHRD_INFINIBAND))
+ return false;
+
if (family == AF_INET6 && !socket_ipv6_is_supported())
return false;
if (!FLAGS_SET(network->link_local, ADDRESS_FAMILY_IPV6) &&
FLAGS_SET(network->dhcp, ADDRESS_FAMILY_IPV6)) {
- log_warning("%s: DHCPv6 client is enabled but IPv6 link local addressing is disabled. "
+ log_warning("%s: DHCPv6 client is enabled but IPv6 link-local addressing is disabled. "
"Disabling DHCPv6 client.", network->filename);
SET_FLAG(network->dhcp, ADDRESS_FAMILY_IPV6, false);
}
}
static int get_product_uuid_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
- Manager *manager = userdata;
+ Manager *manager = ASSERT_PTR(userdata);
const sd_bus_error *e;
const void *a;
size_t sz;
int r;
assert(m);
- assert(manager);
/* To avoid calling GetProductUUID() bus method so frequently, set the flag below
* even if the method fails. */
m->product_uuid_requested = false;
- r = sd_bus_call_method_async(
+ r = bus_call_method_async(
m->bus,
NULL,
- "org.freedesktop.hostname1",
- "/org/freedesktop/hostname1",
- "org.freedesktop.hostname1",
+ bus_hostname,
"GetProductUUID",
get_product_uuid_handler,
m,
return 0;
}
- switch(ltype) {
+ switch (ltype) {
case AF_INET:
network->dhcp_route_metric = metric;
network->dhcp_route_metric_set = true;
return 0;
}
- switch(ltype) {
+ switch (ltype) {
case AF_INET:
network->dhcp_use_dns = r;
network->dhcp_use_dns_set = true;
return 0;
}
- switch(ltype) {
+ switch (ltype) {
case AF_INET:
network->dhcp_use_domains = d;
network->dhcp_use_domains_set = true;
return 0;
}
- switch(ltype) {
+ switch (ltype) {
case AF_INET:
network->dhcp_use_ntp = r;
network->dhcp_use_ntp_set = true;
void *data,
void *userdata) {
- Network *network = userdata;
+ Network *network = ASSERT_PTR(userdata);
uint32_t rt;
int r;
assert(filename);
assert(lvalue);
- assert(IN_SET(ltype,
- (RTPROT_DHCP<<16) | AF_UNSPEC,
- (RTPROT_DHCP<<16) | AF_INET,
- (RTPROT_DHCP<<16) | AF_INET6,
- (RTPROT_RA<<16) | AF_INET6));
+ assert(IN_SET(ltype, AF_INET, AF_INET6));
assert(rvalue);
- assert(data);
r = safe_atou32(rvalue, &rt);
if (r < 0) {
return 0;
}
- switch(ltype) {
- case (RTPROT_DHCP<<16) | AF_INET:
+ switch (ltype) {
+ case AF_INET:
network->dhcp_route_table = rt;
network->dhcp_route_table_set = true;
- network->dhcp_route_table_set_explicitly = true;
break;
- case (RTPROT_DHCP<<16) | AF_INET6:
- network->dhcp6_route_table = rt;
- network->dhcp6_route_table_set = true;
- network->dhcp6_route_table_set_explicitly = true;
- break;
- case (RTPROT_DHCP<<16) | AF_UNSPEC:
- /* For backward compatibility. */
- if (!network->dhcp_route_table_set_explicitly) {
- network->dhcp_route_table = rt;
- network->dhcp_route_table_set = true;
- }
- if (!network->dhcp6_route_table_set_explicitly) {
- network->dhcp6_route_table = rt;
- network->dhcp6_route_table_set = true;
- }
- break;
- case (RTPROT_RA<<16) | AF_INET6:
+ case AF_INET6:
network->ipv6_accept_ra_route_table = rt;
network->ipv6_accept_ra_route_table_set = true;
break;
void *data,
void *userdata) {
- Network *network = userdata;
+ Network *network = ASSERT_PTR(userdata);
uint32_t iaid;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
- assert(network);
assert(IN_SET(ltype, AF_INET, AF_INET6));
r = safe_atou32(rvalue, &iaid);
void *data,
void *userdata) {
- char ***l = data;
+ char ***l = ASSERT_PTR(data);
int r;
- assert(l);
assert(lvalue);
assert(rvalue);
assert(IN_SET(ltype, AF_INET, AF_INET6));
void *data,
void *userdata) {
- _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_(sd_dhcp_option_unrefp) sd_dhcp_option *opt4 = NULL;
+ _cleanup_(sd_dhcp6_option_unrefp) sd_dhcp6_option *opt6 = NULL;
+ _unused_ _cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *old4 = NULL;
+ _unused_ _cleanup_(sd_dhcp6_option_unrefp) sd_dhcp6_option *old6 = NULL;
uint32_t uint32_data, enterprise_identifier = 0;
_cleanup_free_ char *word = NULL, *q = NULL;
- OrderedHashmap **options = data;
+ OrderedHashmap **options = ASSERT_PTR(data);
uint16_t u16, uint16_data;
union in_addr_union addr;
DHCPOptionDataType type;
assert(filename);
assert(lvalue);
assert(rvalue);
- assert(data);
if (isempty(rvalue)) {
*options = ordered_hashmap_free(*options);
return 0;
}
- switch(type) {
+ switch (type) {
case DHCP_OPTION_DATA_UINT8:{
r = safe_atou8(p, &uint8_data);
if (r < 0) {
void *userdata) {
_cleanup_free_ char *type_string = NULL;
- const char *p = rvalue;
+ const char *p = ASSERT_PTR(rvalue);
bool force = ltype;
- DUID *duid = data;
+ DUID *duid = ASSERT_PTR(data);
DUIDType type;
int r;
assert(filename);
assert(lvalue);
- assert(rvalue);
- assert(duid);
if (!force && duid->set)
return 0;
void *data,
void *userdata) {
- Manager *manager = userdata;
+ Manager *manager = ASSERT_PTR(userdata);
int r;
- assert(manager);
-
/* For backward compatibility. Setting both DHCPv4 and DHCPv6 DUID if they are not specified explicitly. */
r = config_parse_duid_type(unit, filename, line, section, section_line, lvalue, false, rvalue, &manager->dhcp_duid, manager);
void *data,
void *userdata) {
- Network *network = userdata;
+ Network *network = ASSERT_PTR(userdata);
int r;
- assert(network);
-
r = config_parse_duid_type(unit, filename, line, section, section_line, lvalue, true, rvalue, &network->dhcp_duid, network);
if (r < 0)
return r;
uint8_t raw_data[MAX_DUID_LEN];
unsigned count = 0;
bool force = ltype;
- DUID *duid = data;
+ DUID *duid = ASSERT_PTR(data);
assert(filename);
assert(lvalue);
assert(rvalue);
- assert(duid);
if (!force && duid->set)
return 0;
void *data,
void *userdata) {
- Manager *manager = userdata;
+ Manager *manager = ASSERT_PTR(userdata);
int r;
- assert(manager);
-
/* For backward compatibility. Setting both DHCPv4 and DHCPv6 DUID if they are not specified explicitly. */
r = config_parse_duid_rawdata(unit, filename, line, section, section_line, lvalue, false, rvalue, &manager->dhcp_duid, manager);
void *data,
void *userdata) {
- Network *network = userdata;
+ Network *network = ASSERT_PTR(userdata);
int r;
- assert(network);
-
r = config_parse_duid_rawdata(unit, filename, line, section, section_line, lvalue, true, rvalue, &network->dhcp_duid, network);
if (r < 0)
return r;
return config_parse_duid_rawdata(unit, filename, line, section, section_line, lvalue, false, rvalue, &network->dhcp6_duid, network);
}
-int config_parse_address_filter(
+int config_parse_uplink(
const char *unit,
const char *filename,
unsigned line,
void *data,
void *userdata) {
- Set **list = data;
- int r;
+ Network *network = ASSERT_PTR(userdata);
+ bool accept_none = true;
+ int *index, r;
+ char **name;
assert(filename);
+ assert(section);
assert(lvalue);
- assert(IN_SET(ltype, AF_INET, AF_INET6));
assert(rvalue);
- assert(data);
- if (isempty(rvalue)) {
- *list = set_free(*list);
+ if (streq(section, "DHCPServer")) {
+ index = &network->dhcp_server_uplink_index;
+ name = &network->dhcp_server_uplink_name;
+ } else if (streq(section, "IPv6SendRA")) {
+ index = &network->router_uplink_index;
+ name = &network->router_uplink_name;
+ } else if (STR_IN_SET(section, "DHCPv6PrefixDelegation", "DHCPPrefixDelegation")) {
+ index = &network->dhcp_pd_uplink_index;
+ name = &network->dhcp_pd_uplink_name;
+ accept_none = false;
+ } else
+ assert_not_reached();
+
+ if (isempty(rvalue) || streq(rvalue, ":auto")) {
+ *index = UPLINK_INDEX_AUTO;
+ *name = mfree(*name);
return 0;
}
- for (const char *p = rvalue;;) {
- _cleanup_free_ char *n = NULL;
- _cleanup_free_ struct in_addr_prefix *a = NULL;
- struct in_addr_prefix prefix;
-
- r = extract_first_word(&p, &n, NULL, 0);
- if (r == -ENOMEM)
- return log_oom();
- if (r < 0) {
- log_syntax(unit, LOG_WARNING, filename, line, r,
- "Failed to parse NDisc %s=, ignoring assignment: %s",
- lvalue, rvalue);
- return 0;
- }
- if (r == 0)
- return 0;
+ if (accept_none && streq(rvalue, ":none")) {
+ *index = UPLINK_INDEX_NONE;
+ *name = mfree(*name);
+ return 0;
+ }
- r = in_addr_prefix_from_string(n, ltype, &prefix.address, &prefix.prefixlen);
- if (r < 0) {
- log_syntax(unit, LOG_WARNING, filename, line, r,
- "NDisc %s= entry is invalid, ignoring assignment: %s",
- lvalue, n);
- continue;
- }
+ if (!accept_none && streq(rvalue, ":self")) {
+ *index = UPLINK_INDEX_SELF;
+ *name = mfree(*name);
+ return 0;
+ }
- prefix.family = ltype;
- a = newdup(struct in_addr_prefix, &prefix, 1);
- if (!a)
- return log_oom();
+ r = parse_ifindex(rvalue);
+ if (r > 0) {
+ *index = r;
+ *name = mfree(*name);
+ return 0;
+ }
- r = set_ensure_consume(list, &in_addr_prefix_hash_ops_free, TAKE_PTR(a));
- if (r < 0)
- return log_oom();
- if (r == 0)
- log_syntax(unit, LOG_WARNING, filename, line, 0,
- "%s %s= entry is duplicated, ignoring assignment: %s",
- section, lvalue, n);
+ if (!ifname_valid_full(rvalue, IFNAME_VALID_ALTERNATIVE)) {
+ log_syntax(unit, LOG_WARNING, filename, line, 0,
+ "Invalid interface name in %s=, ignoring assignment: %s", lvalue, rvalue);
+ return 0;
}
+
+ /* The interface name will be resolved later. */
+ r = free_and_strdup_warn(name, rvalue);
+ if (r < 0)
+ return r;
+
+ /* Note, if uplink_name is set, then uplink_index will be ignored. So, the below does not mean
+ * an uplink interface will be selected automatically. */
+ *index = UPLINK_INDEX_AUTO;
+ return 0;
}