Skip to content

Commit 3e7b9f7

Browse files
27opoettering
authored andcommitted
dhcp: bind udp sockets to interfaces (systemd#4822)
1 parent 73e383c commit 3e7b9f7

File tree

5 files changed

+18
-6
lines changed

5 files changed

+18
-6
lines changed

src/libsystemd-network/dhcp-internal.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@
3030
#include "dhcp-protocol.h"
3131
#include "socket-util.h"
3232

33-
int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link,
33+
int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
3434
uint32_t xid, const uint8_t *mac_addr,
3535
size_t mac_addr_len, uint16_t arp_type,
3636
uint16_t port);
37-
int dhcp_network_bind_udp_socket(be32_t address, uint16_t port);
37+
int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port);
3838
int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
3939
const void *packet, size_t len);
4040
int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,

src/libsystemd-network/dhcp-network.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include <errno.h>
2121
#include <net/ethernet.h>
22+
#include <net/if.h>
2223
#include <net/if_arp.h>
2324
#include <stdio.h>
2425
#include <string.h>
@@ -156,13 +157,14 @@ int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
156157
bcast_addr, &eth_mac, arp_type, dhcp_hlen, port);
157158
}
158159

159-
int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) {
160+
int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port) {
160161
union sockaddr_union src = {
161162
.in.sin_family = AF_INET,
162163
.in.sin_port = htobe16(port),
163164
.in.sin_addr.s_addr = address,
164165
};
165166
_cleanup_close_ int s = -1;
167+
char ifname[IF_NAMESIZE] = "";
166168
int r, on = 1, tos = IPTOS_CLASS_CS6;
167169

168170
s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
@@ -177,6 +179,15 @@ int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) {
177179
if (r < 0)
178180
return -errno;
179181

182+
if (ifindex > 0) {
183+
if (if_indextoname(ifindex, ifname) == 0)
184+
return -errno;
185+
186+
r = setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname));
187+
if (r < 0)
188+
return -errno;
189+
}
190+
180191
if (address == INADDR_ANY) {
181192
r = setsockopt(s, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on));
182193
if (r < 0)
@@ -185,6 +196,7 @@ int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) {
185196
r = setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
186197
if (r < 0)
187198
return -errno;
199+
188200
} else {
189201
r = setsockopt(s, IPPROTO_IP, IP_FREEBIND, &on, sizeof(on));
190202
if (r < 0)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1546,7 +1546,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
15461546
goto error;
15471547
}
15481548

1549-
r = dhcp_network_bind_udp_socket(client->lease->address, client->port);
1549+
r = dhcp_network_bind_udp_socket(client->ifindex, client->lease->address, client->port);
15501550
if (r < 0) {
15511551
log_dhcp_client(client, "could not bind UDP socket");
15521552
goto error;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1022,7 +1022,7 @@ int sd_dhcp_server_start(sd_dhcp_server *server) {
10221022
}
10231023
server->fd_raw = r;
10241024

1025-
r = dhcp_network_bind_udp_socket(INADDR_ANY, DHCP_PORT_SERVER);
1025+
r = dhcp_network_bind_udp_socket(server->ifindex, INADDR_ANY, DHCP_PORT_SERVER);
10261026
if (r < 0) {
10271027
sd_dhcp_server_stop(server);
10281028
return r;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ int dhcp_network_bind_raw_socket(
203203
return test_fd[0];
204204
}
205205

206-
int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) {
206+
int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port) {
207207
int fd;
208208

209209
fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);

0 commit comments

Comments
 (0)