]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/dnsmasq/0092-Allow-T1-and-T2-DHCPv4-options-to-be-set.patch
dnsmasq: Import patches from upstream
[ipfire-2.x.git] / src / patches / dnsmasq / 0092-Allow-T1-and-T2-DHCPv4-options-to-be-set.patch
CommitLineData
efbd3a9a
MT
1From ca85a28241ef87919d68d52c843b6964b7070e11 Mon Sep 17 00:00:00 2001
2From: Simon Kelley <simon@thekelleys.org.uk>
3Date: Wed, 13 May 2015 22:33:04 +0100
4Subject: [PATCH 92/98] Allow T1 and T2 DHCPv4 options to be set.
5
6---
7 CHANGELOG | 3 +++
8 dnsmasq.conf.example | 8 ++++++
9 src/dhcp-common.c | 4 +--
10 src/rfc2131.c | 71 ++++++++++++++++++++++++++++++++++++----------------
11 4 files changed, 63 insertions(+), 23 deletions(-)
12
13diff --git a/CHANGELOG b/CHANGELOG
14index 94a521f996e2..ef39a415788b 100644
15--- a/CHANGELOG
16+++ b/CHANGELOG
17@@ -118,6 +118,9 @@ version 2.73
18 Check IPv4-mapped IPv6 addresses when --stop-rebind
19 is active. Thanks to Jordan Milne for spotting this.
20
21+ Allow DHCPv4 options T1 and T2 to be set using --dhcp-option.
22+ Thanks to Kevin Benton for patches and work on this.
23+
24
25 version 2.72
26 Add ra-advrouter mode, for RFC-3775 mobile IPv6 support.
27diff --git a/dnsmasq.conf.example b/dnsmasq.conf.example
28index 67be99acb028..1ae11dfb5358 100644
29--- a/dnsmasq.conf.example
30+++ b/dnsmasq.conf.example
31@@ -345,6 +345,14 @@
32 # Ask client to poll for option changes every six hours. (RFC4242)
33 #dhcp-option=option6:information-refresh-time,6h
34
35+# Set option 58 client renewal time (T1). Defaults to half of the
36+# lease time if not specified. (RFC2132)
37+#dhcp-option=option:T1:1m
38+
39+# Set option 59 rebinding time (T2). Defaults to 7/8 of the
40+# lease time if not specified. (RFC2132)
41+#dhcp-option=option:T2:2m
42+
43 # Set the NTP time server address to be the same machine as
44 # is running dnsmasq
45 #dhcp-option=42,0.0.0.0
46diff --git a/src/dhcp-common.c b/src/dhcp-common.c
47index ce115202a646..bc48f41a14d7 100644
48--- a/src/dhcp-common.c
49+++ b/src/dhcp-common.c
50@@ -545,8 +545,8 @@ static const struct opttab_t {
51 { "parameter-request", 55, OT_INTERNAL },
52 { "message", 56, OT_INTERNAL },
53 { "max-message-size", 57, OT_INTERNAL },
54- { "T1", 58, OT_INTERNAL | OT_TIME},
55- { "T2", 59, OT_INTERNAL | OT_TIME},
56+ { "T1", 58, OT_TIME},
57+ { "T2", 59, OT_TIME},
58 { "vendor-class", 60, 0 },
59 { "client-id", 61, OT_INTERNAL },
60 { "nis+-domain", 64, OT_NAME },
61diff --git a/src/rfc2131.c b/src/rfc2131.c
62index 55526443dc84..a10e499ef768 100644
63--- a/src/rfc2131.c
64+++ b/src/rfc2131.c
65@@ -52,7 +52,9 @@ static void do_options(struct dhcp_context *context,
66 int null_term, int pxearch,
67 unsigned char *uuid,
68 int vendor_class_len,
69- time_t now);
70+ time_t now,
71+ unsigned int lease_time,
72+ unsigned short fuzz);
73
74
75 static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt);
76@@ -610,7 +612,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
77
78 clear_packet(mess, end);
79 do_options(context, mess, end, NULL, hostname, get_domain(mess->yiaddr),
80- netid, subnet_addr, 0, 0, -1, NULL, vendor_class_len, now);
81+ netid, subnet_addr, 0, 0, -1, NULL, vendor_class_len, now, 0xffffffff, 0);
82 }
83 }
84
85@@ -1042,13 +1044,8 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
86 option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
87 option_put(mess, end, OPTION_LEASE_TIME, 4, time);
88 /* T1 and T2 are required in DHCPOFFER by HP's wacky Jetdirect client. */
89- if (time != 0xffffffff)
90- {
91- option_put(mess, end, OPTION_T1, 4, (time/2));
92- option_put(mess, end, OPTION_T2, 4, (time*7)/8);
93- }
94 do_options(context, mess, end, req_options, offer_hostname, get_domain(mess->yiaddr),
95- netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now);
96+ netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now, time, fuzz);
97
98 return dhcp_packet_size(mess, agent_id, real_end);
99
100@@ -1367,15 +1364,8 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
101 option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
102 option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
103 option_put(mess, end, OPTION_LEASE_TIME, 4, time);
104- if (time != 0xffffffff)
105- {
106- while (fuzz > (time/16))
107- fuzz = fuzz/2;
108- option_put(mess, end, OPTION_T1, 4, (time/2) - fuzz);
109- option_put(mess, end, OPTION_T2, 4, ((time/8)*7) - fuzz);
110- }
111 do_options(context, mess, end, req_options, hostname, get_domain(mess->yiaddr),
112- netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now);
113+ netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now, time, fuzz);
114 }
115
116 return dhcp_packet_size(mess, agent_id, real_end);
117@@ -1440,7 +1430,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
118 }
119
120 do_options(context, mess, end, req_options, hostname, get_domain(mess->ciaddr),
121- netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now);
122+ netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now, 0xffffffff, 0);
123
124 *is_inform = 1; /* handle reply differently */
125 return dhcp_packet_size(mess, agent_id, real_end);
126@@ -2137,7 +2127,9 @@ static void do_options(struct dhcp_context *context,
127 int null_term, int pxe_arch,
128 unsigned char *uuid,
129 int vendor_class_len,
130- time_t now)
131+ time_t now,
132+ unsigned int lease_time,
133+ unsigned short fuzz)
134 {
135 struct dhcp_opt *opt, *config_opts = daemon->dhcp_opts;
136 struct dhcp_boot *boot;
137@@ -2261,7 +2253,42 @@ static void do_options(struct dhcp_context *context,
138 /* rfc3011 says this doesn't need to be in the requested options list. */
139 if (subnet_addr.s_addr)
140 option_put(mess, end, OPTION_SUBNET_SELECT, INADDRSZ, ntohl(subnet_addr.s_addr));
141-
142+
143+ if (lease_time != 0xffffffff)
144+ {
145+ unsigned int t1val = lease_time/2;
146+ unsigned int t2val = (lease_time*7)/8;
147+ unsigned int hval;
148+
149+ /* If set by user, sanity check, so not longer than lease. */
150+ if ((opt = option_find2(OPTION_T1)))
151+ {
152+ hval = ntohl(*((unsigned int *)opt->val));
153+ if (hval < lease_time && hval > 2)
154+ t1val = hval;
155+ }
156+
157+ if ((opt = option_find2(OPTION_T2)))
158+ {
159+ hval = ntohl(*((unsigned int *)opt->val));
160+ if (hval < lease_time && hval > 2)
161+ t2val = hval;
162+ }
163+
164+ while (fuzz > (t1val/8))
165+ fuzz = fuzz/2;
166+
167+ t1val -= fuzz;
168+ t2val -= fuzz;
169+
170+ /* ensure T1 is still < T2 */
171+ if (t2val <= t1val)
172+ t1val = t2val - 1;
173+
174+ option_put(mess, end, OPTION_T1, 4, t1val);
175+ option_put(mess, end, OPTION_T2, 4, t2val);
176+ }
177+
178 /* replies to DHCPINFORM may not have a valid context */
179 if (context)
180 {
181@@ -2356,12 +2383,14 @@ static void do_options(struct dhcp_context *context,
182 if (!(opt->flags & DHOPT_FORCE) && !in_list(req_options, optno))
183 continue;
184
185- /* prohibit some used-internally options */
186+ /* prohibit some used-internally options. T1 and T2 already handled. */
187 if (optno == OPTION_CLIENT_FQDN ||
188 optno == OPTION_MAXMESSAGE ||
189 optno == OPTION_OVERLOAD ||
190 optno == OPTION_PAD ||
191- optno == OPTION_END)
192+ optno == OPTION_END ||
193+ optno == OPTION_T1 ||
194+ optno == OPTION_T2)
195 continue;
196
197 if (optno == OPTION_SNAME && done_server)
198--
1992.1.0
200