Blame SOURCES/dnsmasq-2.76-rh1752569.patch

d7059b
From 3d27384fc5f2a437b7bce128c8ba62e8d6e12df7 Mon Sep 17 00:00:00 2001
d7059b
From: Brian Haley <haleyb.dev@gmail.com>
d7059b
Date: Wed, 28 Aug 2019 16:13:23 -0400
d7059b
Subject: [PATCH] Change dhcp_release to use default address when no IP subnet
d7059b
 matches
d7059b
d7059b
Currently, dhcp_release will only send a 'fake' release
d7059b
when the address given is in the same subnet as an IP
d7059b
on the interface that was given.
d7059b
d7059b
This doesn't work in an environment where dnsmasq is
d7059b
managing leases for remote subnets via a DHCP relay, as
d7059b
running dhcp_release locally will just cause it to
d7059b
silently exit without doing anything, leaving the lease
d7059b
in the database.
d7059b
d7059b
Change it to use the default IP on the interface, as the
d7059b
dnsmasq source code at src/dhcp.c does, if no matching subnet
d7059b
IP is found, as a fall-back.  This fixes an issue we are
d7059b
seeing in certain Openstack deployments where we are using
d7059b
dnsmasq to provision baremetal systems in a datacenter.
d7059b
d7059b
While using Dbus might have seemed like an obvious solution,
d7059b
because of our extensive use of network namespaces (which
d7059b
Dbus doesn't support), this seemed like a better solution
d7059b
than creating system.d policy files for each dnsmasq we
d7059b
might spawn and using --enable-dbus=$id in order to isolate
d7059b
messages to specific dnsmasq instances.
d7059b
d7059b
Signed-off-by: Brian Haley <haleyb.dev@gmail.com>
d7059b
(cherry picked from commit d9f882bea2806799bf3d1f73937f5e72d0bfc650)
d7059b
---
d7059b
 contrib/lease-tools/dhcp_release.c | 12 +++++++++---
d7059b
 1 file changed, 9 insertions(+), 3 deletions(-)
d7059b
d7059b
diff --git a/contrib/lease-tools/dhcp_release.c b/contrib/lease-tools/dhcp_release.c
d7059b
index a51f04b..1dd8d32 100644
d7059b
--- a/contrib/lease-tools/dhcp_release.c
d7059b
+++ b/contrib/lease-tools/dhcp_release.c
d7059b
@@ -178,7 +178,7 @@ static int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask)
d7059b
   return (a.s_addr & mask.s_addr) == (b.s_addr & mask.s_addr);
d7059b
 }
d7059b
 
d7059b
-static struct in_addr find_interface(struct in_addr client, int fd, unsigned int index)
d7059b
+static struct in_addr find_interface(struct in_addr client, int fd, unsigned int index, int ifrfd, struct ifreq *ifr)
d7059b
 {
d7059b
   struct sockaddr_nl addr;
d7059b
   struct nlmsghdr *h;
d7059b
@@ -218,7 +218,13 @@ static struct in_addr find_interface(struct in_addr client, int fd, unsigned int
d7059b
 
d7059b
       for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
d7059b
 	if (h->nlmsg_type == NLMSG_DONE)
d7059b
-	  exit(0);
d7059b
+          {
d7059b
+	    /* No match found, return first address as src/dhcp.c code does */
d7059b
+	    ifr->ifr_addr.sa_family = AF_INET;
d7059b
+	    if (ioctl(ifrfd, SIOCGIFADDR, ifr) != -1)
d7059b
+	      return ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
d7059b
+	    exit(0);
d7059b
+          }
d7059b
 	else if (h->nlmsg_type == RTM_NEWADDR)
d7059b
           {
d7059b
             struct ifaddrmsg *ifa = NLMSG_DATA(h);  
d7059b
@@ -284,7 +290,7 @@ int main(int argc, char **argv)
d7059b
     }
d7059b
   
d7059b
   lease.s_addr = inet_addr(argv[2]);
d7059b
-  server = find_interface(lease, nl, if_nametoindex(argv[1]));
d7059b
+  server = find_interface(lease, nl, if_nametoindex(argv[1]), fd, &ifr);
d7059b
   
d7059b
   memset(&packet, 0, sizeof(packet));
d7059b
  
d7059b
-- 
d7059b
2.20.1
d7059b