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>
This commit is contained in:
parent
4fdb67cc65
commit
5827167338
@ -39,7 +39,21 @@ config FEATURE_UDHCPD_WRITE_LEASES_EARLY
|
||||
If selected, udhcpd will write a new file with leases every
|
||||
time a new lease has been accepted, thus eliminating the need
|
||||
to send SIGUSR1 for the initial writing or updating. Any timed
|
||||
rewriting remains undisturbed
|
||||
rewriting remains undisturbed.
|
||||
|
||||
config FEATURE_UDHCPD_BASE_IP_ON_MAC
|
||||
bool "Select IP address based on client MAC"
|
||||
default n
|
||||
depends on UDHCPD
|
||||
help
|
||||
If selected, udhcpd will base its selection of IP address to offer
|
||||
on the client's hardware address. Otherwise udhcpd uses the next
|
||||
consecutive free address.
|
||||
|
||||
This reduces the frequency of IP address changes for clients
|
||||
which let their lease expire, and makes consecutive DHCPOFFERS
|
||||
for the same client to (almost always) contain the same
|
||||
IP address.
|
||||
|
||||
config DHCPD_LEASES_FILE
|
||||
string "Absolute path to lease file"
|
||||
@ -72,7 +86,7 @@ config FEATURE_UDHCPC_ARPING
|
||||
|
||||
config FEATURE_UDHCP_PORT
|
||||
bool "Enable '-P port' option for udhcpd and udhcpc"
|
||||
default y
|
||||
default n
|
||||
depends on UDHCPD || UDHCPC
|
||||
help
|
||||
At the cost of ~300 bytes, enables -P port option.
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user