optionally set socket priority on DHCPv4 raw socket

This commit is contained in:
chris
2023-01-12 13:26:47 +09:00
committed by Yu Watanabe
parent c24b0bd1df
commit ea57796854
12 changed files with 111 additions and 9 deletions
+3 -1
View File
@@ -40,7 +40,9 @@ int dhcp_network_bind_raw_socket(
const struct hw_addr_data *hw_addr,
const struct hw_addr_data *bcast_addr,
uint16_t arp_type,
uint16_t port);
uint16_t port,
bool so_priority_set,
int so_priority);
int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port, int ip_service_type);
int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
const void *packet, size_t len);
+14 -4
View File
@@ -25,7 +25,9 @@ static int _bind_raw_socket(
const struct hw_addr_data *hw_addr,
const struct hw_addr_data *bcast_addr,
uint16_t arp_type,
uint16_t port) {
uint16_t port,
bool so_priority_set,
int so_priority) {
assert(ifindex > 0);
assert(link);
@@ -113,6 +115,12 @@ static int _bind_raw_socket(
if (r < 0)
return -errno;
if (so_priority_set) {
r = setsockopt_int(s, SOL_SOCKET, SO_PRIORITY, so_priority);
if (r < 0)
return r;
}
link->ll = (struct sockaddr_ll) {
.sll_family = AF_PACKET,
.sll_protocol = htobe16(ETH_P_IP),
@@ -137,7 +145,9 @@ int dhcp_network_bind_raw_socket(
const struct hw_addr_data *hw_addr,
const struct hw_addr_data *bcast_addr,
uint16_t arp_type,
uint16_t port) {
uint16_t port,
bool so_priority_set,
int so_priority) {
static struct hw_addr_data default_eth_bcast = {
.length = ETH_ALEN,
@@ -160,13 +170,13 @@ int dhcp_network_bind_raw_socket(
return _bind_raw_socket(ifindex, link, xid,
hw_addr,
(bcast_addr && !hw_addr_is_null(bcast_addr)) ? bcast_addr : &default_eth_bcast,
arp_type, port);
arp_type, port, so_priority_set, so_priority);
case ARPHRD_INFINIBAND:
return _bind_raw_socket(ifindex, link, xid,
&HW_ADDR_NULL,
(bcast_addr && !hw_addr_is_null(bcast_addr)) ? bcast_addr : &default_ib_bcast,
arp_type, port);
arp_type, port, so_priority_set, so_priority);
default:
return -EINVAL;
}
+4 -1
View File
@@ -16,7 +16,10 @@ int dhcp_network_bind_raw_socket(
uint32_t id,
const struct hw_addr_data *hw_addr,
const struct hw_addr_data *bcast_addr,
uint16_t arp_type, uint16_t port) {
uint16_t arp_type,
uint16_t port,
bool so_priority_set,
int so_priority) {
int fd;
fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
+16 -2
View File
@@ -121,6 +121,8 @@ struct sd_dhcp_client {
sd_dhcp_lease *lease;
usec_t start_delay;
int ip_service_type;
int socket_priority;
bool socket_priority_set;
/* Ignore machine-ID when generating DUID. See dhcp_identifier_set_duid_en(). */
bool test_mode;
@@ -647,6 +649,16 @@ int sd_dhcp_client_set_service_type(sd_dhcp_client *client, int type) {
return 0;
}
int sd_dhcp_client_set_socket_priority(sd_dhcp_client *client, int socket_priority) {
assert_return(client, -EINVAL);
assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
client->socket_priority_set = true;
client->socket_priority = socket_priority;
return 0;
}
int sd_dhcp_client_set_fallback_lease_lifetime(sd_dhcp_client *client, uint32_t fallback_lease_lifetime) {
assert_return(client, -EINVAL);
assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
@@ -1381,7 +1393,8 @@ static int client_start_delayed(sd_dhcp_client *client) {
r = dhcp_network_bind_raw_socket(client->ifindex, &client->link, client->xid,
&client->hw_addr, &client->bcast_addr,
client->arp_type, client->port);
client->arp_type, client->port,
client->socket_priority_set, client->socket_priority);
if (r < 0) {
client_stop(client, r);
return r;
@@ -1429,7 +1442,8 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata)
r = dhcp_network_bind_raw_socket(client->ifindex, &client->link, client->xid,
&client->hw_addr, &client->bcast_addr,
client->arp_type, client->port);
client->arp_type, client->port,
client->socket_priority_set, client->socket_priority);
if (r < 0) {
client_stop(client, r);
return 0;
+4 -1
View File
@@ -235,7 +235,10 @@ int dhcp_network_bind_raw_socket(
uint32_t id,
const struct hw_addr_data *_hw_addr,
const struct hw_addr_data *_bcast_addr,
uint16_t arp_type, uint16_t port) {
uint16_t arp_type,
uint16_t port,
bool so_priority_set,
int so_priority) {
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) < 0)
return -errno;
+42
View File
@@ -1499,6 +1499,12 @@ static int dhcp4_configure(Link *link) {
return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set IP service type: %m");
}
if (link->network->dhcp_socket_priority_set) {
r = sd_dhcp_client_set_socket_priority(link->dhcp_client, link->network->dhcp_socket_priority);
if (r < 0)
return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set socket priority: %m");
}
if (link->network->dhcp_fallback_lease_lifetime > 0) {
r = sd_dhcp_client_set_fallback_lease_lifetime(link->dhcp_client, link->network->dhcp_fallback_lease_lifetime);
if (r < 0)
@@ -1701,6 +1707,42 @@ int config_parse_dhcp_ip_service_type(
return 0;
}
int config_parse_dhcp_socket_priority(
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) {
Network *network = ASSERT_PTR(data);
int a, r;
assert(lvalue);
assert(rvalue);
if (isempty(rvalue)) {
network->dhcp_socket_priority_set = false;
return 0;
}
r = safe_atoi(rvalue, &a);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse socket priority, ignoring: %s", rvalue);
return 0;
}
network->dhcp_socket_priority_set = true;
network->dhcp_socket_priority = a;
return 0;
}
int config_parse_dhcp_fallback_lease_lifetime(
const char *unit,
const char *filename,
+1
View File
@@ -29,6 +29,7 @@ int link_request_dhcp4_client(Link *link);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_client_identifier);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_max_attempts);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_ip_service_type);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_socket_priority);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_mud_url);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_fallback_lease_lifetime);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_label);
+1
View File
@@ -243,6 +243,7 @@ DHCPv4.SendDecline, config_parse_bool,
DHCPv4.DenyList, config_parse_in_addr_prefixes, AF_INET, offsetof(Network, dhcp_deny_listed_ip)
DHCPv4.AllowList, config_parse_in_addr_prefixes, AF_INET, offsetof(Network, dhcp_allow_listed_ip)
DHCPv4.IPServiceType, config_parse_dhcp_ip_service_type, 0, offsetof(Network, dhcp_ip_service_type)
DHCPv4.SocketPriority, config_parse_dhcp_socket_priority, 0, 0
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)
+2
View File
@@ -130,6 +130,8 @@ struct Network {
uint16_t dhcp_client_port;
int dhcp_critical;
int dhcp_ip_service_type;
int dhcp_socket_priority;
bool dhcp_socket_priority_set;
bool dhcp_anonymize;
bool dhcp_send_hostname;
int dhcp_broadcast;
+3
View File
@@ -309,6 +309,9 @@ int sd_dhcp_client_get_lease(
int sd_dhcp_client_set_service_type(
sd_dhcp_client *client,
int type);
int sd_dhcp_client_set_socket_priority(
sd_dhcp_client *client,
int so_priority);
int sd_dhcp_client_set_fallback_lease_lifetime(
sd_dhcp_client *client,
uint32_t fallback_lease_lifetime);