Blame SOURCES/dnsmasq-2.76-rh1752569.patch

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