summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Ivicic <martin.ivicic@pan-net.eu>2024-02-21 02:07:26 +0100
committerYu Watanabe <watanabe.yu+github@gmail.com>2024-02-21 11:33:27 +0100
commitea932bd34d000ebaa33f95c2e125200c13ba88cb (patch)
tree974cdf0177cd569cb9eec49c53af5a4907911bab
parentnetwork: DHCP6 Allow to export DHCP6 DUID (#31355) (diff)
downloadsystemd-ea932bd34d000ebaa33f95c2e125200c13ba88cb.tar.xz
systemd-ea932bd34d000ebaa33f95c2e125200c13ba88cb.zip
networkd: support setting dhcp server port
-rw-r--r--man/systemd.network.xml9
-rw-r--r--src/libsystemd-network/sd-dhcp-client.c22
-rw-r--r--src/network/networkd-dhcp4.c5
-rw-r--r--src/network/networkd-network-gperf.gperf1
-rw-r--r--src/network/networkd-network.h1
-rw-r--r--src/systemd/sd-dhcp-client.h3
6 files changed, 37 insertions, 4 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 32de0ce844..adff23d1fe 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -2737,6 +2737,15 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix</programlisting>
</varlistentry>
<varlistentry>
+ <term><varname>ServerPort=</varname></term>
+ <listitem>
+ <para>Set the port on which the DHCP server is listening.</para>
+
+ <xi:include href="version-info.xml" xpointer="v256"/>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>DenyList=</varname></term>
<listitem>
<para>A whitespace-separated list of IPv4 addresses. Each address can optionally take a
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 395f7ce4d0..1eb8509f0f 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 b34120f997..71b132f94f 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 a196da7f0f..236bac7aa6 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 270ffd87a3..e9ee556312 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 dcbd79e6b4..1483afa220 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);