Skip to content

Commit 9faed22

Browse files
ssahanikeszybz
authored andcommitted
networkd: support setting dhcp client listen port (systemd#4631)
Allow setting custom port for the DHCP client to listen on in networkd. [DHCP] ListenPort=6677
1 parent a1ef6bd commit 9faed22

File tree

10 files changed

+50
-16
lines changed

10 files changed

+50
-16
lines changed

man/systemd.network.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,13 @@
984984
</para>
985985
</listitem>
986986
</varlistentry>
987+
988+
<varlistentry>
989+
<term><varname>ListenPort=</varname></term>
990+
<listitem>
991+
<para>Allow setting custom port for the DHCP client to listen on.</para>
992+
</listitem>
993+
</varlistentry>
987994
</variablelist>
988995
</refsect1>
989996

src/libsystemd-network/dhcp-internal.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232

3333
int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link,
3434
uint32_t xid, const uint8_t *mac_addr,
35-
size_t mac_addr_len, uint16_t arp_type);
35+
size_t mac_addr_len, uint16_t arp_type,
36+
uint16_t port);
3637
int dhcp_network_bind_udp_socket(be32_t address, uint16_t port);
3738
int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
3839
const void *packet, size_t len);
@@ -57,7 +58,7 @@ void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr,
5758
uint16_t source, be32_t destination_addr,
5859
uint16_t destination, uint16_t len);
5960

60-
int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum);
61+
int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum, uint16_t port);
6162

6263
/* If we are invoking callbacks of a dhcp-client, ensure unreffing the
6364
* client from the callback doesn't destroy the object we are working

src/libsystemd-network/dhcp-network.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
3636
size_t mac_addr_len,
3737
const uint8_t *bcast_addr,
3838
const struct ether_addr *eth_mac,
39-
uint16_t arp_type, uint8_t dhcp_hlen) {
39+
uint16_t arp_type, uint8_t dhcp_hlen,
40+
uint16_t port) {
4041
struct sock_filter filter[] = {
4142
BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), /* A <- packet length */
4243
BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(DHCPPacket), 1, 0), /* packet >= DHCPPacket ? */
@@ -53,7 +54,7 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
5354
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0), /* A == 0 ? */
5455
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
5556
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, udp.dest)), /* A <- UDP destination port */
56-
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_PORT_CLIENT, 1, 0), /* UDP destination port == DHCP client port ? */
57+
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, port, 1, 0), /* UDP destination port == DHCP client port ? */
5758
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
5859
BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.op)), /* A <- DHCP op */
5960
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, BOOTREPLY, 1, 0), /* op == BOOTREPLY ? */
@@ -125,7 +126,8 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
125126

126127
int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
127128
uint32_t xid, const uint8_t *mac_addr,
128-
size_t mac_addr_len, uint16_t arp_type) {
129+
size_t mac_addr_len, uint16_t arp_type,
130+
uint16_t port) {
129131
static const uint8_t eth_bcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
130132
/* Default broadcast address for IPoIB */
131133
static const uint8_t ib_bcast[] = {
@@ -151,7 +153,7 @@ int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
151153
return -EINVAL;
152154

153155
return _bind_raw_socket(ifindex, link, xid, mac_addr, mac_addr_len,
154-
bcast_addr, &eth_mac, arp_type, dhcp_hlen);
156+
bcast_addr, &eth_mac, arp_type, dhcp_hlen, port);
155157
}
156158

157159
int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) {

src/libsystemd-network/dhcp-packet.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr,
114114
packet->ip.check = dhcp_packet_checksum((uint8_t*)&packet->ip, DHCP_IP_SIZE);
115115
}
116116

117-
int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum) {
117+
int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum, uint16_t port) {
118118
size_t hdrlen;
119119

120120
assert(packet);
@@ -160,10 +160,10 @@ int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum) {
160160
return -EINVAL;
161161
}
162162

163-
if (be16toh(packet->udp.dest) != DHCP_PORT_CLIENT) {
163+
if (be16toh(packet->udp.dest) != port) {
164164
log_debug("ignoring packet: to port %u, which "
165165
"is not the DHCP client port (%u)",
166-
be16toh(packet->udp.dest), DHCP_PORT_CLIENT);
166+
be16toh(packet->udp.dest), port);
167167
return -EINVAL;
168168
}
169169

src/libsystemd-network/sd-dhcp-client.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ struct sd_dhcp_client {
5555
sd_event_source *timeout_resend;
5656
int ifindex;
5757
int fd;
58+
uint16_t port;
5859
union sockaddr_union link;
5960
sd_event_source *receive_message;
6061
bool request_broadcast;
@@ -426,6 +427,17 @@ int sd_dhcp_client_set_vendor_class_identifier(
426427
return 0;
427428
}
428429

430+
int sd_dhcp_client_set_client_port(
431+
sd_dhcp_client *client,
432+
uint16_t port) {
433+
434+
assert_return(client, -EINVAL);
435+
436+
client->port = port;
437+
438+
return 0;
439+
}
440+
429441
int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu) {
430442
assert_return(client, -EINVAL);
431443
assert_return(mtu >= DHCP_DEFAULT_MIN_SIZE, -ERANGE);
@@ -668,7 +680,7 @@ static int dhcp_client_send_raw(
668680
DHCPPacket *packet,
669681
size_t len) {
670682

671-
dhcp_packet_append_ip_headers(packet, INADDR_ANY, DHCP_PORT_CLIENT,
683+
dhcp_packet_append_ip_headers(packet, INADDR_ANY, client->port,
672684
INADDR_BROADCAST, DHCP_PORT_SERVER, len);
673685

674686
return dhcp_network_send_raw_socket(client->fd, &client->link,
@@ -1120,7 +1132,7 @@ static int client_start_delayed(sd_dhcp_client *client) {
11201132

11211133
r = dhcp_network_bind_raw_socket(client->ifindex, &client->link,
11221134
client->xid, client->mac_addr,
1123-
client->mac_addr_len, client->arp_type);
1135+
client->mac_addr_len, client->arp_type, client->port);
11241136
if (r < 0) {
11251137
client_stop(client, r);
11261138
return r;
@@ -1170,7 +1182,8 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata)
11701182

11711183
r = dhcp_network_bind_raw_socket(client->ifindex, &client->link,
11721184
client->xid, client->mac_addr,
1173-
client->mac_addr_len, client->arp_type);
1185+
client->mac_addr_len, client->arp_type,
1186+
client->port);
11741187
if (r < 0) {
11751188
client_stop(client, r);
11761189
return 0;
@@ -1555,8 +1568,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
15551568
goto error;
15561569
}
15571570

1558-
r = dhcp_network_bind_udp_socket(client->lease->address,
1559-
DHCP_PORT_CLIENT);
1571+
r = dhcp_network_bind_udp_socket(client->lease->address, client->port);
15601572
if (r < 0) {
15611573
log_dhcp_client(client, "could not bind UDP socket");
15621574
goto error;
@@ -1766,7 +1778,7 @@ static int client_receive_message_raw(
17661778
}
17671779
}
17681780

1769-
r = dhcp_packet_verify_headers(packet, len, checksum);
1781+
r = dhcp_packet_verify_headers(packet, len, checksum, client->port);
17701782
if (r < 0)
17711783
return 0;
17721784

@@ -1891,6 +1903,7 @@ int sd_dhcp_client_new(sd_dhcp_client **ret) {
18911903
client->fd = -1;
18921904
client->attempt = 1;
18931905
client->mtu = DHCP_DEFAULT_MIN_SIZE;
1906+
client->port = DHCP_PORT_CLIENT;
18941907

18951908
client->req_opts_size = ELEMENTSOF(default_req_opts);
18961909
client->req_opts = memdup(default_req_opts, client->req_opts_size);

src/libsystemd-network/test-dhcp-client.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ int dhcp_network_bind_raw_socket(
195195
union sockaddr_union *link,
196196
uint32_t id,
197197
const uint8_t *addr, size_t addr_len,
198-
uint16_t arp_type) {
198+
uint16_t arp_type, uint16_t port) {
199199

200200
if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_fd) < 0)
201201
return -errno;

src/network/networkd-dhcp4.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,12 @@ int dhcp4_configure(Link *link) {
630630
return r;
631631
}
632632

633+
if (link->network->dhcp_client_port) {
634+
r = sd_dhcp_client_set_client_port(link->dhcp_client, link->network->dhcp_client_port);
635+
if (r < 0)
636+
return r;
637+
}
638+
633639
switch (link->network->dhcp_client_identifier) {
634640
case DHCP_CLIENT_ID_DUID: {
635641
/* If configured, apply user specified DUID and/or IAID */

src/network/networkd-network-gperf.gperf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ DHCP.RouteMetric, config_parse_unsigned,
100100
DHCP.RouteTable, config_parse_dhcp_route_table, 0, offsetof(Network, dhcp_route_table)
101101
DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone)
102102
DHCP.IAID, config_parse_iaid, 0, offsetof(Network, iaid)
103+
DHCP.ListenPort, config_parse_uint32, 0, offsetof(Network, dhcp_client_port)
103104
IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns)
104105
IPv6AcceptRA.UseDomains, config_parse_dhcp_use_domains, 0, offsetof(Network, ipv6_accept_ra_use_domains)
105106
IPv6AcceptRA.RouteTable, config_parse_dhcp_route_table, 0, offsetof(Network, ipv6_accept_ra_route_table)

src/network/networkd-network.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ struct Network {
124124
bool dhcp_use_timezone;
125125
unsigned dhcp_route_metric;
126126
uint32_t dhcp_route_table;
127+
uint32_t dhcp_client_port;
127128

128129
/* DHCP Server Support */
129130
bool dhcp_server;

src/systemd/sd-dhcp-client.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ int sd_dhcp_client_get_client_id(
126126
int sd_dhcp_client_set_mtu(
127127
sd_dhcp_client *client,
128128
uint32_t mtu);
129+
int sd_dhcp_client_set_client_port(
130+
sd_dhcp_client *client,
131+
uint16_t port);
129132
int sd_dhcp_client_set_hostname(
130133
sd_dhcp_client *client,
131134
const char *hostname);

0 commit comments

Comments
 (0)