diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 32de0ce8446..adff23d1fed 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -2736,6 +2736,15 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix + + ServerPort= + + Set the port on which the DHCP server is listening. + + + + + DenyList= diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 395f7ce4d04..1eb8509f0f6 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -62,6 +62,7 @@ struct sd_dhcp_client { int fd; uint16_t port; + uint16_t server_port; union sockaddr_union link; sd_event_source *receive_message; bool request_broadcast; @@ -516,6 +517,18 @@ int sd_dhcp_client_set_client_port( return 0; } +int sd_dhcp_client_set_port( + sd_dhcp_client *client, + uint16_t port) { + + assert_return(client, -EINVAL); + assert_return(!sd_dhcp_client_is_running(client), -EBUSY); + + client->server_port = port; + + return 0; +} + int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu) { assert_return(client, -EINVAL); assert_return(mtu >= DHCP_MIN_PACKET_SIZE, -ERANGE); @@ -891,7 +904,7 @@ static int dhcp_client_send_raw( size_t len) { dhcp_packet_append_ip_headers(packet, INADDR_ANY, client->port, - INADDR_BROADCAST, DHCP_PORT_SERVER, len, client->ip_service_type); + INADDR_BROADCAST, client->server_port, len, client->ip_service_type); return dhcp_network_send_raw_socket(client->fd, &client->link, packet, len); @@ -1113,7 +1126,7 @@ static int client_send_request(sd_dhcp_client *client) { if (client->state == DHCP_STATE_RENEWING) r = dhcp_network_send_udp_socket(client->fd, client->lease->server_address, - DHCP_PORT_SERVER, + client->server_port, &request->dhcp, sizeof(DHCPMessage) + optoffset); else @@ -2203,7 +2216,7 @@ int sd_dhcp_client_send_release(sd_dhcp_client *client) { r = dhcp_network_send_udp_socket(client->fd, client->lease->server_address, - DHCP_PORT_SERVER, + client->server_port, &release->dhcp, sizeof(DHCPMessage) + optoffset); if (r < 0) @@ -2237,7 +2250,7 @@ int sd_dhcp_client_send_decline(sd_dhcp_client *client) { r = dhcp_network_send_udp_socket(client->fd, client->lease->server_address, - DHCP_PORT_SERVER, + client->server_port, &release->dhcp, sizeof(DHCPMessage) + optoffset); if (r < 0) @@ -2382,6 +2395,7 @@ int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize) { .fd = -EBADF, .mtu = DHCP_MIN_PACKET_SIZE, .port = DHCP_PORT_CLIENT, + .server_port = DHCP_PORT_SERVER, .anonymize = !!anonymize, .max_discover_attempts = UINT64_MAX, .max_request_attempts = 5, diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index b34120f9970..71b132f94f5 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -1634,6 +1634,11 @@ static int dhcp4_configure(Link *link) { if (r < 0) return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set listen port: %m"); } + if (link->network->dhcp_port > 0) { + r = sd_dhcp_client_set_port(link->dhcp_client, link->network->dhcp_port); + if (r < 0) + return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set server port: %m"); + } if (link->network->dhcp_max_attempts > 0) { r = sd_dhcp_client_set_max_attempts(link->dhcp_client, link->network->dhcp_max_attempts); diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index a196da7f0f9..236bac7aa67 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -248,6 +248,7 @@ DHCPv4.RouteMetric, config_parse_dhcp_route_metric, DHCPv4.RouteTable, config_parse_dhcp_or_ra_route_table, AF_INET, 0 DHCPv4.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone) DHCPv4.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port) +DHCPv4.ServerPort, config_parse_uint16, 0, offsetof(Network, dhcp_port) DHCPv4.SendRelease, config_parse_bool, 0, offsetof(Network, dhcp_send_release) DHCPv4.SendDecline, config_parse_bool, 0, offsetof(Network, dhcp_send_decline) DHCPv4.DenyList, config_parse_in_addr_prefixes, AF_INET, offsetof(Network, dhcp_deny_listed_ip) diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 270ffd87a3a..e9ee556312b 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -132,6 +132,7 @@ struct Network { usec_t dhcp_fallback_lease_lifetime_usec; uint32_t dhcp_route_mtu; uint16_t dhcp_client_port; + uint16_t dhcp_port; int dhcp_critical; int dhcp_ip_service_type; int dhcp_socket_priority; diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h index dcbd79e6b4d..1483afa2203 100644 --- a/src/systemd/sd-dhcp-client.h +++ b/src/systemd/sd-dhcp-client.h @@ -120,6 +120,9 @@ int sd_dhcp_client_set_max_attempts( int sd_dhcp_client_set_client_port( sd_dhcp_client *client, uint16_t port); +int sd_dhcp_client_set_port( + sd_dhcp_client *client, + uint16_t port); int sd_dhcp_client_set_hostname( sd_dhcp_client *client, const char *hostname);