diff options
author | Vladislav Grishenko <themiron@mail.ru> | 2011-02-16 13:31:30 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-02-16 13:31:30 +0100 |
commit | 582716733895946b2729acdf18a32532567b973a (patch) | |
tree | 433dbc03b2c71768c4477d0f3f4e41c95dc2fa66 | |
parent | 4fdb67cc65e93967448bb28e4cb810ad5648bfea (diff) | |
download | busybox-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.src | 18 | ||||
-rw-r--r-- | networking/udhcp/leases.c | 40 |
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 | |||
44 | config 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 | ||
44 | config DHCPD_LEASES_FILE | 58 | config 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 | ||
73 | config FEATURE_UDHCP_PORT | 87 | config 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) |