]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/dnsmasq/0060-dhcp-set-outbound-interface-via-cmsg-in-unicast-repl.patch
Merge remote-tracking branch 'stevee/core-90-geoip' into next
[ipfire-2.x.git] / src / patches / dnsmasq / 0060-dhcp-set-outbound-interface-via-cmsg-in-unicast-repl.patch
CommitLineData
c6ce1e7e
MT
1From 65c721200023ef0023114459a8d12f8b0a24cfd8 Mon Sep 17 00:00:00 2001
2From: Lung-Pin Chang <changlp@cs.nctu.edu.tw>
3Date: Thu, 19 Mar 2015 23:22:21 +0000
d54a2ce4 4Subject: [PATCH 60/78] dhcp: set outbound interface via cmsg in unicast reply
c6ce1e7e
MT
5
6 If multiple routes to the same network exist, Linux blindly picks
7 the first interface (route) based on destination address, which might not be
8 the one we're actually offering leases. Rather than relying on this,
9 always set the interface for outgoing unicast DHCP packets.
10---
11 src/dhcp.c | 45 +++++++++++++++++++++++++--------------------
12 1 file changed, 25 insertions(+), 20 deletions(-)
13
14diff --git a/src/dhcp.c b/src/dhcp.c
15index 5c3089ab94ff..f1f43f8d8f90 100644
16--- a/src/dhcp.c
17+++ b/src/dhcp.c
18@@ -376,10 +376,9 @@ void dhcp_packet(time_t now, int pxe_fd)
19 }
20 }
21 #if defined(HAVE_LINUX_NETWORK)
22- else if ((ntohs(mess->flags) & 0x8000) || mess->hlen == 0 ||
23- mess->hlen > sizeof(ifr.ifr_addr.sa_data) || mess->htype == 0)
24+ else
25 {
26- /* broadcast to 255.255.255.255 (or mac address invalid) */
27+ /* fill cmsg for outbound interface (both broadcast & unicast) */
28 struct in_pktinfo *pkt;
29 msg.msg_control = control_u.control;
30 msg.msg_controllen = sizeof(control_u);
31@@ -389,23 +388,29 @@ void dhcp_packet(time_t now, int pxe_fd)
32 pkt->ipi_spec_dst.s_addr = 0;
33 msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
34 cmptr->cmsg_level = IPPROTO_IP;
35- cmptr->cmsg_type = IP_PKTINFO;
36- dest.sin_addr.s_addr = INADDR_BROADCAST;
37- dest.sin_port = htons(daemon->dhcp_client_port);
38- }
39- else
40- {
41- /* unicast to unconfigured client. Inject mac address direct into ARP cache.
42- struct sockaddr limits size to 14 bytes. */
43- dest.sin_addr = mess->yiaddr;
44- dest.sin_port = htons(daemon->dhcp_client_port);
45- memcpy(&arp_req.arp_pa, &dest, sizeof(struct sockaddr_in));
46- arp_req.arp_ha.sa_family = mess->htype;
47- memcpy(arp_req.arp_ha.sa_data, mess->chaddr, mess->hlen);
48- /* interface name already copied in */
49- arp_req.arp_flags = ATF_COM;
50- if (ioctl(daemon->dhcpfd, SIOCSARP, &arp_req) == -1)
51- my_syslog(MS_DHCP | LOG_ERR, _("ARP-cache injection failed: %s"), strerror(errno));
52+ cmptr->cmsg_type = IP_PKTINFO;
53+
54+ if ((ntohs(mess->flags) & 0x8000) || mess->hlen == 0 ||
55+ mess->hlen > sizeof(ifr.ifr_addr.sa_data) || mess->htype == 0)
56+ {
57+ /* broadcast to 255.255.255.255 (or mac address invalid) */
58+ dest.sin_addr.s_addr = INADDR_BROADCAST;
59+ dest.sin_port = htons(daemon->dhcp_client_port);
60+ }
61+ else
62+ {
63+ /* unicast to unconfigured client. Inject mac address direct into ARP cache.
64+ struct sockaddr limits size to 14 bytes. */
65+ dest.sin_addr = mess->yiaddr;
66+ dest.sin_port = htons(daemon->dhcp_client_port);
67+ memcpy(&arp_req.arp_pa, &dest, sizeof(struct sockaddr_in));
68+ arp_req.arp_ha.sa_family = mess->htype;
69+ memcpy(arp_req.arp_ha.sa_data, mess->chaddr, mess->hlen);
70+ /* interface name already copied in */
71+ arp_req.arp_flags = ATF_COM;
72+ if (ioctl(daemon->dhcpfd, SIOCSARP, &arp_req) == -1)
73+ my_syslog(MS_DHCP | LOG_ERR, _("ARP-cache injection failed: %s"), strerror(errno));
74+ }
75 }
76 #elif defined(HAVE_SOLARIS_NETWORK)
77 else if ((ntohs(mess->flags) & 0x8000) || mess->hlen != ETHER_ADDR_LEN || mess->htype != ARPHRD_ETHER)
78--
792.1.0
80