aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Grishenko <themiron@mail.ru>2011-02-16 13:31:30 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2011-02-16 13:31:30 +0100
commit582716733895946b2729acdf18a32532567b973a (patch)
tree433dbc03b2c71768c4477d0f3f4e41c95dc2fa66
parent4fdb67cc65e93967448bb28e4cb810ad5648bfea (diff)
downloadbusybox-w32-582716733895946b2729acdf18a32532567b973a.tar.gz
busybox-w32-582716733895946b2729acdf18a32532567b973a.tar.bz2
busybox-w32-582716733895946b2729acdf18a32532567b973a.zip
udhcpd: optional IP selection based on MAC hash
function old new delta find_free_or_expired_nip 153 225 +72 Signed-off-by: Vladislav Grishenko <themiron@mail.ru> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/udhcp/Config.src18
-rw-r--r--networking/udhcp/leases.c40
2 files changed, 50 insertions, 8 deletions
diff --git a/networking/udhcp/Config.src b/networking/udhcp/Config.src
index dcd493f13..750a53a32 100644
--- a/networking/udhcp/Config.src
+++ b/networking/udhcp/Config.src
@@ -39,7 +39,21 @@ config FEATURE_UDHCPD_WRITE_LEASES_EARLY
39 If selected, udhcpd will write a new file with leases every 39 If selected, udhcpd will write a new file with leases every
40 time a new lease has been accepted, thus eliminating the need 40 time a new lease has been accepted, thus eliminating the need
41 to send SIGUSR1 for the initial writing or updating. Any timed 41 to send SIGUSR1 for the initial writing or updating. Any timed
42 rewriting remains undisturbed 42 rewriting remains undisturbed.
43
44config FEATURE_UDHCPD_BASE_IP_ON_MAC
45 bool "Select IP address based on client MAC"
46 default n
47 depends on UDHCPD
48 help
49 If selected, udhcpd will base its selection of IP address to offer
50 on the client's hardware address. Otherwise udhcpd uses the next
51 consecutive free address.
52
53 This reduces the frequency of IP address changes for clients
54 which let their lease expire, and makes consecutive DHCPOFFERS
55 for the same client to (almost always) contain the same
56 IP address.
43 57
44config DHCPD_LEASES_FILE 58config DHCPD_LEASES_FILE
45 string "Absolute path to lease file" 59 string "Absolute path to lease file"
@@ -72,7 +86,7 @@ config FEATURE_UDHCPC_ARPING
72 86
73config FEATURE_UDHCP_PORT 87config FEATURE_UDHCP_PORT
74 bool "Enable '-P port' option for udhcpd and udhcpc" 88 bool "Enable '-P port' option for udhcpd and udhcpc"
75 default y 89 default n
76 depends on UDHCPD || UDHCPC 90 depends on UDHCPD || UDHCPC
77 help 91 help
78 At the cost of ~300 bytes, enables -P port option. 92 At the cost of ~300 bytes, enables -P port option.
diff --git a/networking/udhcp/leases.c b/networking/udhcp/leases.c
index 7aeb37bae..c5b60b108 100644
--- a/networking/udhcp/leases.c
+++ b/networking/udhcp/leases.c
@@ -137,21 +137,42 @@ uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac)
137 uint32_t addr; 137 uint32_t addr;
138 struct dyn_lease *oldest_lease = NULL; 138 struct dyn_lease *oldest_lease = NULL;
139 139
140 addr = server_config.start_ip; /* addr is in host order here */ 140#if ENABLE_FEATURE_UDHCPD_BASE_IP_ON_MAC
141 for (; addr <= server_config.end_ip; addr++) { 141 uint32_t stop;
142 unsigned i, hash;
143
144 /* hash hwaddr: use the SDBM hashing algorithm. Seems to give good
145 * dispersal even with similarly-valued "strings".
146 */
147 hash = 0;
148 for (i = 0; i < 6; i++)
149 hash += safe_mac[i] + (hash << 6) + (hash << 16) - hash;
150
151 /* pick a seed based on hwaddr then iterate until we find a free address. */
152 addr = server_config.start_ip
153 + (hash % (1 + server_config.end_ip - server_config.start_ip));
154 stop = addr;
155#else
156 addr = server_config.start_ip;
157#define stop (server_config.end_ip + 1)
158#endif
159 do {
142 uint32_t nip; 160 uint32_t nip;
143 struct dyn_lease *lease; 161 struct dyn_lease *lease;
144 162
145 /* ie, 192.168.55.0 */ 163 /* ie, 192.168.55.0 */
146 if ((addr & 0xff) == 0) 164 if ((addr & 0xff) == 0)
147 continue; 165 goto next_addr;
148 /* ie, 192.168.55.255 */ 166 /* ie, 192.168.55.255 */
149 if ((addr & 0xff) == 0xff) 167 if ((addr & 0xff) == 0xff)
150 continue; 168 goto next_addr;
151 nip = htonl(addr); 169 nip = htonl(addr);
170 /* skip our own address */
171 if (nip == server_config.server_nip)
172 goto next_addr;
152 /* is this a static lease addr? */ 173 /* is this a static lease addr? */
153 if (is_nip_reserved(server_config.static_leases, nip)) 174 if (is_nip_reserved(server_config.static_leases, nip))
154 continue; 175 goto next_addr;
155 176
156 lease = find_lease_by_nip(nip); 177 lease = find_lease_by_nip(nip);
157 if (!lease) { 178 if (!lease) {
@@ -162,7 +183,14 @@ uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac)
162 if (!oldest_lease || lease->expires < oldest_lease->expires) 183 if (!oldest_lease || lease->expires < oldest_lease->expires)
163 oldest_lease = lease; 184 oldest_lease = lease;
164 } 185 }
165 } 186
187 next_addr:
188 addr++;
189#if ENABLE_FEATURE_UDHCPD_BASE_IP_ON_MAC
190 if (addr > server_config.end_ip)
191 addr = server_config.start_ip;
192#endif
193 } while (addr != stop);
166 194
167 if (oldest_lease 195 if (oldest_lease
168 && is_expired_lease(oldest_lease) 196 && is_expired_lease(oldest_lease)