]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/dnsmasq/0092-Allow-T1-and-T2-DHCPv4-options-to-be-set.patch
Merge branch 'next' of ssh://git.ipfire.org/pub/git/ipfire-2.x into next
[ipfire-2.x.git] / src / patches / dnsmasq / 0092-Allow-T1-and-T2-DHCPv4-options-to-be-set.patch
1 From ca85a28241ef87919d68d52c843b6964b7070e11 Mon Sep 17 00:00:00 2001
2 From: Simon Kelley <simon@thekelleys.org.uk>
3 Date: Wed, 13 May 2015 22:33:04 +0100
4 Subject: [PATCH 092/113] 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
13 diff --git a/CHANGELOG b/CHANGELOG
14 index 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.
27 diff --git a/dnsmasq.conf.example b/dnsmasq.conf.example
28 index 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
46 diff --git a/src/dhcp-common.c b/src/dhcp-common.c
47 index 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 },
61 diff --git a/src/rfc2131.c b/src/rfc2131.c
62 index 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 --
199 2.1.0