Simon Kelley | 208b65c | 2006-08-05 21:41:37 +0100 | [diff] [blame] | 1 | This script can be used to implement persistent leases on openWRT, DD-WRT |
| 2 | etc. Persistent leases are good: if the lease database is lost on a |
| 3 | reboot, then it will eventually be restored as hosts renew their |
| 4 | leases. Until a host renews (which may take hours/days) it will |
| 5 | not exist in the DNS if dnsmasq's DDNS function is in use. |
| 6 | |
Josh Soref | 730c674 | 2017-02-06 16:14:04 +0000 | [diff] [blame] | 7 | *WRT systems remount all non-volatile filesystems read-only after boot, |
Simon Kelley | 208b65c | 2006-08-05 21:41:37 +0100 | [diff] [blame] | 8 | so the normal leasefile will not work. They do, however have NV |
| 9 | storage, accessed with the nvram command: |
| 10 | |
| 11 | /usr/lib # nvram |
| 12 | usage: nvram [get name] [set name=value] [unset name] [show] |
| 13 | |
| 14 | The principle is that leases are kept in NV variable with data |
| 15 | corresponding to the line in a leasefile: |
| 16 | |
| 17 | dnsmasq_lease_192.168.1.56=3600 00:41:4a:05:80:74 192.168.1.56 * * |
| 18 | |
| 19 | By giving dnsmasq the leasefile-ro command, it no longer creates or writes a |
| 20 | leasefile; responsibility for maintaining the lease database transfers |
| 21 | to the lease change script. At startup, in leasefile-ro mode, |
| 22 | dnsmasq will run |
| 23 | |
| 24 | "<lease_change_script> init" |
| 25 | |
| 26 | and read whatever that command spits out, expecting it to |
| 27 | be in dnsmasq leasefile format. |
| 28 | |
| 29 | So the lease change script, given "init" as argv[1] will |
| 30 | suck existing leases out of the NVRAM and emit them from |
| 31 | stdout in the correct format. |
| 32 | |
| 33 | The second part of the problem is keeping the NVRAM up-to-date: this |
| 34 | is done by the lease-change script which dnsmasq runs when a lease is |
| 35 | updated. When it is called with argv[1] as "old", "add", or "del" |
| 36 | it updates the relevant nvram entry. |
| 37 | |
| 38 | So, dnsmasq should be run as : |
| 39 | |
| 40 | dnsmasq --leasefile-ro --dhcp-script=/path/to/lease_update.sh |
| 41 | |
| 42 | or the same flags added to /etc/dnsmasq.conf |
| 43 | |
| 44 | |
| 45 | |
| 46 | Notes: |
| 47 | |
| 48 | This needs dnsmasq-2.33 or later to work. |
| 49 | |
| 50 | This technique will work with, or without, compilation with |
| 51 | HAVE_BROKEN_RTC. Compiling with HAVE_BROKEN_RTC is |
| 52 | _highly_recommended_ for this application since is avoids problems |
| 53 | with the system clock being warped by NTP, and it vastly reduces the |
| 54 | number of writes to the NVRAM. With HAVE_BROKEN_RTC, NVRAM is updated |
| 55 | only when a lease is created or destroyed; without it, a write occurs |
| 56 | every time a lease is renewed. |
| 57 | |
| 58 | It probably makes sense to restrict the number of active DHCP leases |
| 59 | to an appropriate number using dhcp-lease-max. On a new DD_WRT system, |
| 60 | there are about 10K bytes free in the NVRAM. Each lease record is |
| 61 | about 100 bytes, so restricting the number of leases to 50 will limit |
| 62 | use to half that. (The default limit in the distributed source is 150) |
| 63 | |
| 64 | Any UI script which reads the dnsmasq leasefile will have to be |
Josh Soref | 730c674 | 2017-02-06 16:14:04 +0000 | [diff] [blame] | 65 | amended, probably by changing it to read the output of |
Simon Kelley | 208b65c | 2006-08-05 21:41:37 +0100 | [diff] [blame] | 66 | `lease_update init` instead. |
| 67 | |
| 68 | |
| 69 | Thanks: |
| 70 | |
| 71 | To Steve Horbachuk for checks on the script and debugging beyond the |
| 72 | call of duty. |
| 73 | |
| 74 | |
| 75 | Simon Kelley |
| 76 | Fri Jul 28 11:51:13 BST 2006 |
| 77 | |
| 78 | |
| 79 | |
| 80 | |
| 81 | |