diff options
author | Vladislav Grishenko | 2011-02-16 13:31:30 +0100 |
---|---|---|
committer | Denys Vlasenko | 2011-02-16 13:31:30 +0100 |
commit | 582716733895946b2729acdf18a32532567b973a (patch) | |
tree | 433dbc03b2c71768c4477d0f3f4e41c95dc2fa66 /networking/udhcp/leases.c | |
parent | 4fdb67cc65e93967448bb28e4cb810ad5648bfea (diff) | |
download | busybox-582716733895946b2729acdf18a32532567b973a.zip busybox-582716733895946b2729acdf18a32532567b973a.tar.gz |
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>
Diffstat (limited to 'networking/udhcp/leases.c')
-rw-r--r-- | networking/udhcp/leases.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/networking/udhcp/leases.c b/networking/udhcp/leases.c index 7aeb37b..c5b60b1 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) uint32_t addr; struct dyn_lease *oldest_lease = NULL; - addr = server_config.start_ip; /* addr is in host order here */ - for (; addr <= server_config.end_ip; addr++) { +#if ENABLE_FEATURE_UDHCPD_BASE_IP_ON_MAC + uint32_t stop; + unsigned i, hash; + + /* hash hwaddr: use the SDBM hashing algorithm. Seems to give good + * dispersal even with similarly-valued "strings". + */ + hash = 0; + for (i = 0; i < 6; i++) + hash += safe_mac[i] + (hash << 6) + (hash << 16) - hash; + + /* pick a seed based on hwaddr then iterate until we find a free address. */ + addr = server_config.start_ip + + (hash % (1 + server_config.end_ip - server_config.start_ip)); + stop = addr; +#else + addr = server_config.start_ip; +#define stop (server_config.end_ip + 1) +#endif + do { uint32_t nip; struct dyn_lease *lease; /* ie, 192.168.55.0 */ if ((addr & 0xff) == 0) - continue; + goto next_addr; /* ie, 192.168.55.255 */ if ((addr & 0xff) == 0xff) - continue; + goto next_addr; nip = htonl(addr); + /* skip our own address */ + if (nip == server_config.server_nip) + goto next_addr; /* is this a static lease addr? */ if (is_nip_reserved(server_config.static_leases, nip)) - continue; + goto next_addr; lease = find_lease_by_nip(nip); if (!lease) { @@ -162,7 +183,14 @@ uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac) if (!oldest_lease || lease->expires < oldest_lease->expires) oldest_lease = lease; } - } + + next_addr: + addr++; +#if ENABLE_FEATURE_UDHCPD_BASE_IP_ON_MAC + if (addr > server_config.end_ip) + addr = server_config.start_ip; +#endif + } while (addr != stop); if (oldest_lease && is_expired_lease(oldest_lease) |