components/dnsmasq/patches/02_compile_dhcp_release.patch
author david.comay@oracle.com
Thu, 10 Jul 2014 13:27:03 -0700
branchs11-update
changeset 3200 16d08ab96b7f
child 6746 5a7cd15a88f8
permissions -rw-r--r--
18686478 kstat warning every minute in nova-compute log on SPARC 19061438 checkboxes related with 'create volume from Image' in the Horizon don't work 19064962 power state mapping for incomplete zone is incorrect 19065445 Horizon doesn't deal well with shutdown zones 19130253 pausing/suspension "successful" in horizon, though nothing happens 19136473 ZFSSA iSCSI Cinder Attach Volume Failed 19146728 missing an upstream utility 'dhcp_release' needed by instance termination 19148389 jsonpointer package missing as a dependency for jsonpatch 19158668 associating a new floating ip removes existing ipnat rules and re-adds them 19161623 problem in SERVICE/KEYSTONE 19166348 cinder & nova should default signing_dir explicitly for consistency 19166359 minor pkgfmt(1) issues with OpenStack manifests 19168609 System Info page doesn't work properly 19173435 problem in SERVICE/HORIZON 19181971 OpenStack pkg.summaries should include service type

Add hooks to compile contrib/wrt/dhcp_release.c. This utility is used to
send a DHCPRELEASE message to tell the local DHCP server to delete a
particular lease.

Solaris doesn't support AF_NETLINK, so use getifaddrs() to determine the
IP address of an interface on which Dnsmasq process is listening.

This patch was developed in-house. Since it is Solaris-specific it is not
suitable for upstream.

--- dnsmasq-2.68/Makefile	2013-12-08 07:58:29.000000000 -0800
+++ NEW/Makefile	2014-07-06 20:06:34.886232993 -0700
@@ -19,6 +19,7 @@
 # Variables you may well want to override.
 
 PREFIX        = /usr/local
+LIBDIR        = $(PREFIX)/lib/inet
 BINDIR        = $(PREFIX)/sbin
 MANDIR        = $(PREFIX)/share/man
 LOCALEDIR     = $(PREFIX)/share/locale
@@ -43,6 +44,7 @@
 SRC = src
 PO  = po
 MAN = man
+WRT = contrib/wrt
 
 #################################################################
 
@@ -67,6 +69,8 @@
        helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o \
        dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o domain.o
 
+dhcp_release_objs = dhcp_release.o
+
 hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
        dns-protocol.h radv-protocol.h
 
@@ -75,11 +79,12 @@
  top="$(top)" \
  build_cflags="$(version) $(dbus_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags)" \
  build_libs="$(dbus_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs)" \
- -f $(top)/Makefile dnsmasq 
+ -f $(top)/Makefile dnsmasq dhcp_release
 
 mostly_clean :
 	rm -f $(BUILDDIR)/*.mo $(BUILDDIR)/*.pot 
-	rm -f $(BUILDDIR)/.configured $(BUILDDIR)/*.o $(BUILDDIR)/dnsmasq.a $(BUILDDIR)/dnsmasq 
+	rm -f $(BUILDDIR)/.configured $(BUILDDIR)/*.o $(BUILDDIR)/dnsmasq.a \
+		$(BUILDDIR)/dnsmasq $(BUILDDIR)/dhcp_release
 
 clean : mostly_clean
 	rm -f $(BUILDDIR)/dnsmasq_baseline
@@ -89,9 +94,11 @@
 install : all install-common
 
 install-common :
-	$(INSTALL) -d $(DESTDIR)$(BINDIR) -d $(DESTDIR)$(MANDIR)/man8
+	$(INSTALL) -d $(DESTDIR)$(BINDIR) -d $(DESTDIR)$(MANDIR)/man8 \
+		-d $(DESTDIR)/$(LIBDIR)
 	$(INSTALL) -m 644 $(MAN)/dnsmasq.8 $(DESTDIR)$(MANDIR)/man8 
 	$(INSTALL) -m 755 $(BUILDDIR)/dnsmasq $(DESTDIR)$(BINDIR)
+	$(INSTALL) -m 755 $(BUILDDIR)/dhcp_release $(DESTDIR)$(LIBDIR)
 
 all-i18n : $(BUILDDIR)
 	@cd $(BUILDDIR) && $(MAKE) \
@@ -99,7 +106,7 @@
  i18n=-DLOCALEDIR=\'\"$(LOCALEDIR)\"\' \
  build_cflags="$(version) $(dbus_cflags) $(ct_cflags) $(lua_cflags) `$(PKG_CONFIG) --cflags libidn`" \
  build_libs="$(dbus_libs) $(ct_libs) $(lua_libs) $(sunos_libs) `$(PKG_CONFIG) --libs libidn`"  \
- -f $(top)/Makefile dnsmasq
+ -f $(top)/Makefile dnsmasq dhcp_release
 	for f in `cd $(PO); echo *.po`; do \
 		cd $(top) && cd $(BUILDDIR) && $(MAKE) top="$(top)" -f $(top)/Makefile $${f%.po}.mo; \
 	done
@@ -142,12 +149,18 @@
 $(objs:.o=.c) $(hdrs):
 	ln -s $(top)/$(SRC)/$@ .
 
+$(dhcp_release_objs:.o=.c):
+	ln -s $(top)/$(WRT)/$@ .
+
 .c.o:
 	$(CC) $(CFLAGS) $(COPTS) $(i18n) $(build_cflags) $(RPM_OPT_FLAGS) -c $<	
 
 dnsmasq : .configured $(hdrs) $(objs)
 	$(CC) $(LDFLAGS) -o $@ $(objs) $(build_libs) $(LIBS) 
 
+dhcp_release : .configured $(hdrs) $(dhcp_release_objs)
+	$(CC) $(LDFLAGS) -o $@ $(dhcp_release_objs) $(build_libs) $(LIBS) 
+
 dnsmasq.pot : $(objs:.o=.c) $(hdrs)
 	$(XGETTEXT) -d dnsmasq --foreign-user --omit-header --keyword=_ -o $@ -i $(objs:.o=.c)
 
--- dnsmasq-2.68/contrib/wrt/dhcp_release.c	2013-12-08 07:58:29.000000000 -0800
+++ NEW/contrib/wrt/dhcp_release.c	2014-07-04 14:57:37.992103839 -0700
@@ -33,6 +33,10 @@
    The client-id is optional. If it is "*" then it treated as being missing.
 */
 
+#if defined(__sun) || defined(__sun__)
+#define HAVE_SOLARIS_NETWORK
+#endif
+
 #include <sys/types.h> 
 #include <netinet/in.h>
 #include <net/if.h>
@@ -44,9 +48,13 @@
 #include <stdlib.h>
 #include <net/if_arp.h>
 #include <sys/ioctl.h>
+#ifdef HAVE_SOLARIS_NETWORK
+#include <ifaddrs.h>
+#else
 #include <linux/types.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
+#endif
 #include <errno.h>
 
 #define DHCP_CHADDR_MAX          16
@@ -73,6 +81,7 @@
   unsigned char options[308];
 };
 
+#if !defined(HAVE_SOLARIS_NETWORK)
 static struct iovec iov;
 
 static int expand_buf(struct iovec *iov, size_t size)
@@ -139,6 +148,8 @@
   return rc;
 }
 
+#endif
+
 static int parse_hex(char *in, unsigned char *out, int maxlen, int *mac_type)
 {
   int i = 0;
@@ -178,6 +189,7 @@
   return (a.s_addr & mask.s_addr) == (b.s_addr & mask.s_addr);
 }
 
+#if !defined(HAVE_SOLARIS_NETWORK)
 static struct in_addr find_interface(struct in_addr client, int fd, unsigned int index)
 {
   struct sockaddr_nl addr;
@@ -244,6 +256,7 @@
  
   exit(0);
 }
+#endif
 
 int main(int argc, char **argv)
 { 
@@ -254,7 +267,11 @@
   struct sockaddr_in dest;
   struct ifreq ifr;
   int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+#ifdef HAVE_SOLARIS_NETWORK
+  int nl = 0;
+#else
   int nl = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+#endif
 
   if (argc < 4 || argc > 5)
     { 
@@ -267,7 +284,8 @@
       perror("cannot create socket");
       exit(1);
     }
-  
+
+#if !defined(HAVE_SOLARIS_NETWORK)
   /* This voodoo fakes up a packet coming from the correct interface, which really matters for 
      a DHCP server */
   strcpy(ifr.ifr_name, argv[1]);
@@ -276,11 +294,43 @@
       perror("cannot setup interface");
       exit(1);
     }
-  
+#endif
   
   lease.s_addr = inet_addr(argv[2]);
+#ifdef HAVE_SOLARIS_NETWORK
+  struct ifaddrs *ifp_head, *ifp;
+
+  if (getifaddrs(&ifp_head) < 0)
+    {
+      perror("could not retrieve IP addresses");
+      exit(1);
+    }
+  for (ifp = ifp_head; ifp != NULL; ifp = ifp->ifa_next) { 
+    if (ifp->ifa_addr->sa_family != AF_INET)
+      continue;
+    if (strcmp(ifp->ifa_name, argv[1]) == 0 &&
+        is_same_net(lease, ((struct sockaddr_in *)ifp->ifa_addr)->sin_addr,
+	((struct sockaddr_in *)ifp->ifa_netmask)->sin_addr))
+      break;
+    }
+  if (ifp == NULL) {
+    freeifaddrs(ifp_head);
+    exit(0);
+  }
+  memcpy(&server, &((struct sockaddr_in *)ifp->ifa_addr)->sin_addr,
+	sizeof(server));
+  /* bind to the socket */
+  if (bind(fd, ifp->ifa_addr, sizeof(struct sockaddr_in)) == -1)
+    {
+      freeifaddrs(ifp_head);
+      perror("cannot bind to socket");
+      exit(1);
+    }
+  freeifaddrs(ifp_head);
+#else
   server = find_interface(lease, nl, if_nametoindex(argv[1]));
-  
+#endif
+
   memset(&packet, 0, sizeof(packet));
  
   packet.hlen = parse_hex(argv[3], packet.chaddr, DHCP_CHADDR_MAX, &mac_type);