Blame SOURCES/dnsmasq-2.76-rh1752569.patch

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