rust/cargo-c: update to 0.10.7+cargo-0.84.0
[oi-userland.git] / components / network / dnsmasq / patches / 04_dhcp_bind_fix.patch
blob22497830829a2cc07150c202b9f0ce58f4449e3e
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
5 suitable for upstream.
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)
12 errno != EPERM)
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.
25 + */
27 + struct irec *iface, *found;
28 + struct iname *if_tmp;
30 + if (!daemon->if_names)
31 + return -1;
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, '*')))
35 + return -1;
37 + for (found = NULL, iface = daemon->interfaces; iface; iface = iface->next)
38 + if (iface->dhcp_ok)
39 + {
40 + if (!found)
41 + found = iface;
42 + else if (strcmp(found->name, iface->name) != 0)
43 + return -1; /* more than one. */
44 + }
46 + if (found)
47 + return found->index;
49 + return -1;
52 +void bindtoif(int ifindex, int fd, int is_dhcp6)
54 + if (is_dhcp6)
55 + {
56 + if (setsockopt(fd, IPPROTO_IPV6, IPV6_BOUND_IF, (char *)&ifindex, sizeof(ifindex)) == -1 &&
57 + errno != EPERM)
58 + die(_("failed to set IPv6_BOUND_IF on DHCP socket: %s"), NULL, EC_BADNET);
59 + }
60 + else
61 + {
62 + if (setsockopt(fd, IPPROTO_IP, IP_BOUND_IF, &ifindex, sizeof(ifindex)) == -1 &&
63 + errno != EPERM)
64 + die(_("failed to set IP_BOUND_IF on DHCP socket: %s"), NULL, EC_BADNET);
65 + }
67 #endif
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
72 @@ -66,6 +66,10 @@
73 #else
74 int bind_fallback = 0;
75 #endif
76 +#if defined(HAVE_SOLARIS_NETWORK)
77 + int bound_ifindex = -1;
78 + int did_bind = 0;
79 +#endif
80 #if defined(HAVE_DHCP) || defined(HAVE_DHCP6)
81 struct dhcp_context *context;
82 struct dhcp_relay *relay;
83 @@ -985,6 +989,10 @@
84 if (netlink_warn)
85 my_syslog(LOG_WARNING, netlink_warn);
86 # endif
87 +# ifdef HAVE_SOLARIS_NETWORK
88 + if (did_bind)
89 + my_syslog(MS_DHCP | LOG_INFO, _("DHCP, sockets bound exclusively to interface index %d"), bound_ifindex);
90 +# endif
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();
101 + if (daemon->dhcp)
103 + if (!daemon->relay4 && bound_ifindex >= 0)
105 + bindtoif(bound_ifindex, daemon->dhcpfd, 0);
106 + did_bind = 1;
109 + if (daemon->enable_pxe && bound_ifindex >= 0)
111 + bindtoif(bound_ifindex, daemon->pxefd, 0);
112 + did_bind = 1;
115 #endif
117 #ifdef HAVE_DHCP6
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
120 @@ -153,6 +153,8 @@
121 #include <sys/prctl.h>
122 #elif defined(HAVE_SOLARIS_NETWORK)
123 #include <priv.h>
124 +int which_ifindex(void);
125 +void bindtoif(int ifindex, int fd, int is_dhcp6);
126 #endif
128 /* Backwards compat with 2.83 */