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
|
If selected, udhcpd will write a new file with leases every
|
||||||
time a new lease has been accepted, thus eliminating the need
|
time a new lease has been accepted, thus eliminating the need
|
||||||
to send SIGUSR1 for the initial writing or updating. Any timed
|
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
|
config DHCPD_LEASES_FILE
|
||||||
string "Absolute path to lease file"
|
string "Absolute path to lease file"
|
||||||
@ -72,7 +86,7 @@ config FEATURE_UDHCPC_ARPING
|
|||||||
|
|
||||||
config FEATURE_UDHCP_PORT
|
config FEATURE_UDHCP_PORT
|
||||||
bool "Enable '-P port' option for udhcpd and udhcpc"
|
bool "Enable '-P port' option for udhcpd and udhcpc"
|
||||||
default y
|
default n
|
||||||
depends on UDHCPD || UDHCPC
|
depends on UDHCPD || UDHCPC
|
||||||
help
|
help
|
||||||
At the cost of ~300 bytes, enables -P port option.
|
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;
|
uint32_t addr;
|
||||||
struct dyn_lease *oldest_lease = NULL;
|
struct dyn_lease *oldest_lease = NULL;
|
||||||
|
|
||||||
addr = server_config.start_ip; /* addr is in host order here */
|
#if ENABLE_FEATURE_UDHCPD_BASE_IP_ON_MAC
|
||||||
for (; addr <= server_config.end_ip; addr++) {
|
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;
|
uint32_t nip;
|
||||||
struct dyn_lease *lease;
|
struct dyn_lease *lease;
|
||||||
|
|
||||||
/* ie, 192.168.55.0 */
|
/* ie, 192.168.55.0 */
|
||||||
if ((addr & 0xff) == 0)
|
if ((addr & 0xff) == 0)
|
||||||
continue;
|
goto next_addr;
|
||||||
/* ie, 192.168.55.255 */
|
/* ie, 192.168.55.255 */
|
||||||
if ((addr & 0xff) == 0xff)
|
if ((addr & 0xff) == 0xff)
|
||||||
continue;
|
goto next_addr;
|
||||||
nip = htonl(addr);
|
nip = htonl(addr);
|
||||||
|
/* skip our own address */
|
||||||
|
if (nip == server_config.server_nip)
|
||||||
|
goto next_addr;
|
||||||
/* is this a static lease addr? */
|
/* is this a static lease addr? */
|
||||||
if (is_nip_reserved(server_config.static_leases, nip))
|
if (is_nip_reserved(server_config.static_leases, nip))
|
||||||
continue;
|
goto next_addr;
|
||||||
|
|
||||||
lease = find_lease_by_nip(nip);
|
lease = find_lease_by_nip(nip);
|
||||||
if (!lease) {
|
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)
|
if (!oldest_lease || lease->expires < oldest_lease->expires)
|
||||||
oldest_lease = lease;
|
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
|
if (oldest_lease
|
||||||
&& is_expired_lease(oldest_lease)
|
&& is_expired_lease(oldest_lease)
|
||||||
|
Loading…
Reference in New Issue
Block a user