1 Patch to address a scalability issue when using dnsmasq in Openstack,
2 that causes DHCP to be extremely slow.
4 This patch was developed in-house. Since it is Solaris-specific, it is not
7 diff --git a/src/dhcp-common.c b/src/dhcp-common.c
8 index befd8a0..4573730 100644
9 --- a/src/dhcp-common.c
10 +++ b/src/dhcp-common.c
11 @@ -550,6 +550,58 @@ void bindtodevice(char *device, int fd)
13 die(_("failed to set SO_BINDTODEVICE on DHCP socket: %s"), NULL, EC_BADNET);
15 +#elif defined(HAVE_SOLARIS_NETWORK)
16 +int which_ifindex(void)
18 + /* If we are doing DHCP on exactly one interface, and using Solaris, we want
19 + * to limit packet transmission/reception to that interface using IP_BOUND_IF
20 + * for IPv4 and IPV6_BOUND_IF for IPv6. This is for the use case of OpenStack,
21 + * which runs a new dnsmasq instance for each network it creates. Without this
22 + * socket option, each of the dnsmasq process would unnecessarily process
23 + * packets that arrive on other interfaces as well, thus slowing down the
24 + * entire DHCP process.
27 + struct irec *iface, *found;
28 + struct iname *if_tmp;
30 + if (!daemon->if_names)
33 + for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
34 + if (if_tmp->name && (!if_tmp->used || strchr(if_tmp->name, '*')))
37 + for (found = NULL, iface = daemon->interfaces; iface; iface = iface->next)
42 + else if (strcmp(found->name, iface->name) != 0)
43 + return -1; /* more than one. */
47 + return found->index;
52 +void bindtoif(int ifindex, int fd, int is_dhcp6)
56 + if (setsockopt(fd, IPPROTO_IPV6, IPV6_BOUND_IF, (char *)&ifindex, sizeof(ifindex)) == -1 &&
58 + die(_("failed to set IPv6_BOUND_IF on DHCP socket: %s"), NULL, EC_BADNET);
62 + if (setsockopt(fd, IPPROTO_IP, IP_BOUND_IF, &ifindex, sizeof(ifindex)) == -1 &&
64 + die(_("failed to set IP_BOUND_IF on DHCP socket: %s"), NULL, EC_BADNET);
69 static const struct opttab_t {
70 --- a/src/dnsmasq.c 2023-02-02 21:24:24.000000000 +0100
71 +++ dnsmasq-2.89/src/dnsmasq.c 2023-05-12 10:54:02.094077940 +0200
74 int bind_fallback = 0;
76 +#if defined(HAVE_SOLARIS_NETWORK)
77 + int bound_ifindex = -1;
80 #if defined(HAVE_DHCP) || defined(HAVE_DHCP6)
81 struct dhcp_context *context;
82 struct dhcp_relay *relay;
85 my_syslog(LOG_WARNING, netlink_warn);
87 +# ifdef HAVE_SOLARIS_NETWORK
89 + my_syslog(MS_DHCP | LOG_INFO, _("DHCP, sockets bound exclusively to interface index %d"), bound_ifindex);
92 /* after dhcp_construct_contexts */
93 if (daemon->dhcp || daemon->doing_dhcp6)
94 @@ -1103,6 +1111,23 @@
95 if (daemon->pxefd != -1)
96 poll_listen(daemon->pxefd, POLLIN);
98 +#elif defined(HAVE_SOLARIS_NETWORK) && defined(HAVE_DHCP)
99 + bound_ifindex = which_ifindex();
103 + if (!daemon->relay4 && bound_ifindex >= 0)
105 + bindtoif(bound_ifindex, daemon->dhcpfd, 0);
109 + if (daemon->enable_pxe && bound_ifindex >= 0)
111 + bindtoif(bound_ifindex, daemon->pxefd, 0);
118 --- a/src/dnsmasq.h 2023-02-02 21:24:24.000000000 +0100
119 +++ dnsmasq-2.89/src/dnsmasq.h 2023-05-12 11:04:20.988219658 +0200
121 #include <sys/prctl.h>
122 #elif defined(HAVE_SOLARIS_NETWORK)
124 +int which_ifindex(void);
125 +void bindtoif(int ifindex, int fd, int is_dhcp6);
128 /* Backwards compat with 2.83 */