From ea577968540db7eb4d9b9922506dc0cad0426ec7 Mon Sep 17 00:00:00 2001 From: chris Date: Sun, 1 Jan 2023 14:59:20 +0100 Subject: optionally set socket priority on DHCPv4 raw socket --- src/libsystemd-network/dhcp-internal.h | 4 +++- src/libsystemd-network/dhcp-network.c | 18 ++++++++++++++---- src/libsystemd-network/fuzz-dhcp-client.c | 5 ++++- src/libsystemd-network/sd-dhcp-client.c | 18 ++++++++++++++++-- src/libsystemd-network/test-dhcp-client.c | 5 ++++- 5 files changed, 41 insertions(+), 9 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/dhcp-internal.h b/src/libsystemd-network/dhcp-internal.h index a311d1d5b9..5a7308c5ac 100644 --- a/src/libsystemd-network/dhcp-internal.h +++ b/src/libsystemd-network/dhcp-internal.h @@ -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); diff --git a/src/libsystemd-network/dhcp-network.c b/src/libsystemd-network/dhcp-network.c index 4e4b1ccb75..9137efa3ee 100644 --- a/src/libsystemd-network/dhcp-network.c +++ b/src/libsystemd-network/dhcp-network.c @@ -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; } diff --git a/src/libsystemd-network/fuzz-dhcp-client.c b/src/libsystemd-network/fuzz-dhcp-client.c index a9cfba90e3..d2bbf660b0 100644 --- a/src/libsystemd-network/fuzz-dhcp-client.c +++ b/src/libsystemd-network/fuzz-dhcp-client.c @@ -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); diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 48174e7c4b..f5abb1bf86 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -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; diff --git a/src/libsystemd-network/test-dhcp-client.c b/src/libsystemd-network/test-dhcp-client.c index 92b9b5b9bc..863649f6df 100644 --- a/src/libsystemd-network/test-dhcp-client.c +++ b/src/libsystemd-network/test-dhcp-client.c @@ -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; -- cgit v1.2.1