aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp/packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/udhcp/packet.c')
-rw-r--r--networking/udhcp/packet.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c
index 51374646d..4d8e005d4 100644
--- a/networking/udhcp/packet.c
+++ b/networking/udhcp/packet.c
@@ -189,7 +189,8 @@ int FAST_FUNC udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt,
/* Let the kernel do all the work for packet generation */
int FAST_FUNC udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
uint32_t source_nip, int source_port,
- uint32_t dest_nip, int dest_port)
+ uint32_t dest_nip, int dest_port,
+ const char *ifname)
{
struct sockaddr_in sa;
unsigned padding;
@@ -204,6 +205,21 @@ int FAST_FUNC udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
}
setsockopt_reuseaddr(fd);
+ /* If interface carrier goes down, unless we
+ * bind socket to a particular netdev, the packet
+ * can go out through another interface, eg. via
+ * default route despite being bound to a specific
+ * source IP. As such, bind to device hard and fail
+ * otherwise. Sending renewal packets on foreign
+ * interfaces makes no sense.
+ */
+ if (ifname) {
+ if (setsockopt_bindtodevice(fd, ifname) < 0) {
+ msg = "bindtodevice";
+ goto ret_close;
+ }
+ }
+
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(source_port);