--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/dnsmasq/patches/05_dhcp_bind_fix.patch Mon Sep 26 16:23:01 2016 -0700
@@ -0,0 +1,139 @@
+Patch to address a scalability issue when using dnsmasq in Openstack,
+that causes DHCP to be extremely slow.
+
+This patch was developed in-house. Since it is Solaris-specific, it is not
+suitable for upstream.
+
+--- dnsmasq-2.75/src/dhcp-common.c 2015-07-30 12:59:07.000000000 -0700
++++ new/src/dhcp-common.c 2016-09-22 15:12:02.104708123 -0700
+@@ -493,6 +493,58 @@
+ errno != EPERM)
+ die(_("failed to set SO_BINDTODEVICE on DHCP socket: %s"), NULL, EC_BADNET);
+ }
++#elif defined(HAVE_SOLARIS_NETWORK)
++int which_ifindex(void)
++{
++ /* If we are doing DHCP on exactly one interface, and using Solaris, we want
++ * to limit packet transmission/reception to that interface using IP_BOUND_IF
++ * for IPv4 and IPV6_BOUND_IF for IPv6. This is for the use case of OpenStack,
++ * which runs a new dnsmasq instance for each network it creates. Without this
++ * socket option, each of the dnsmasq process would unnecessarily process
++ * packets that arrive on other interfaces as well, thus slowing down the
++ * entire DHCP process.
++ */
++
++ struct irec *iface, *found;
++ struct iname *if_tmp;
++
++ if (!daemon->if_names)
++ return -1;
++
++ for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
++ if (if_tmp->name && (!if_tmp->used || strchr(if_tmp->name, '*')))
++ return -1;
++
++ for (found = NULL, iface = daemon->interfaces; iface; iface = iface->next)
++ if (iface->dhcp_ok)
++ {
++ if (!found)
++ found = iface;
++ else if (strcmp(found->name, iface->name) != 0)
++ return -1; /* more than one. */
++ }
++
++ if (found)
++ return found->index;
++
++ return -1;
++}
++
++void bindtoif(int ifindex, int fd, int is_dhcp6)
++{
++ if (is_dhcp6)
++ {
++ if (setsockopt(fd, IPPROTO_IPV6, IPV6_BOUND_IF, (char *)&ifindex, sizeof(ifindex)) == -1 &&
++ errno != EPERM)
++ die(_("failed to set IPv6_BOUND_IF on DHCP socket: %s"), NULL, EC_BADNET);
++ }
++ else
++ {
++ if (setsockopt(fd, IPPROTO_IP, IP_BOUND_IF, &ifindex, sizeof(ifindex)) == -1 &&
++ errno != EPERM)
++ die(_("failed to set IP_BOUND_IF on DHCP socket: %s"), NULL, EC_BADNET);
++ }
++}
+ #endif
+
+ static const struct opttab_t {
+--- dnsmasq-2.75/src/dnsmasq.h 2016-09-22 15:20:19.502011580 -0700
++++ new/src/dnsmasq.h 2016-09-22 13:17:03.865473011 -0700
+@@ -1464,6 +1464,9 @@
+ #ifdef HAVE_LINUX_NETWORK
+ char *whichdevice(void);
+ void bindtodevice(char *device, int fd);
++#elif defined(HAVE_SOLARIS_NETWORK)
++int which_ifindex(void);
++void bindtoif(int ifindex, int fd, int is_dhcp6);
+ #endif
+ # ifdef HAVE_DHCP6
+ void display_opts6(void);
+--- dnsmasq-2.75/src/dnsmasq.c 2015-07-30 12:59:07.000000000 -0700
++++ new/src/dnsmasq.c 2016-09-22 15:20:03.040122945 -0700
+@@ -54,6 +54,10 @@
+ char *bound_device = NULL;
+ int did_bind = 0;
+ #endif
++#if defined(HAVE_SOLARIS_NETWORK)
++ int bound_ifindex = -1;
++ int did_bind = 0;
++#endif
+ #if defined(HAVE_DHCP) || defined(HAVE_DHCP6)
+ struct dhcp_context *context;
+ struct dhcp_relay *relay;
+@@ -306,6 +310,23 @@
+ did_bind = 1;
+ }
+ }
++#elif defined(HAVE_SOLARIS_NETWORK) && defined(HAVE_DHCP)
++ bound_ifindex = which_ifindex();
++
++ if (daemon->dhcp)
++ {
++ if (!daemon->relay4 && bound_ifindex >= 0)
++ {
++ bindtoif(bound_ifindex, daemon->dhcpfd, 0);
++ did_bind = 1;
++ }
++
++ if (daemon->enable_pxe && bound_ifindex >= 0)
++ {
++ bindtoif(bound_ifindex, daemon->pxefd, 0);
++ did_bind = 1;
++ }
++ }
+ #endif
+
+ #if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP6)
+@@ -314,6 +335,12 @@
+ bindtodevice(bound_device, daemon->dhcp6fd);
+ did_bind = 1;
+ }
++#elif defined(HAVE_SOLARIS_NETWORK) && defined(HAVE_DHCP6)
++ if (daemon->doing_dhcp6 && !daemon->relay6 && bound_ifindex >= 0)
++ {
++ bindtoif(bound_ifindex, daemon->dhcp6fd, 1);
++ did_bind = 1;
++ }
+ #endif
+ }
+ else
+@@ -788,6 +815,9 @@
+ # ifdef HAVE_LINUX_NETWORK
+ if (did_bind)
+ my_syslog(MS_DHCP | LOG_INFO, _("DHCP, sockets bound exclusively to interface %s"), bound_device);
++# elif defined(HAVE_SOLARIS_NETWORK)
++ if (did_bind)
++ my_syslog(MS_DHCP | LOG_INFO, _("DHCP, sockets bound exclusively to interface index %d"), bound_ifindex);
+ # endif
+
+ /* after dhcp_contruct_contexts */