return print_string(s, len, dl, data);
}
+ if (type & FLAG) {
+ if (s) {
+ *s++ = '1';
+ *s = '\0';
+ }
+ return 2;
+ }
+
/* DHCPv6 status code */
if (type & SCODE && dl >= (int)sizeof(u16)) {
if (s) {
#define ADDRIPV6 (1 << 14)
#define BINHEX (1 << 15)
#define SCODE (1 << 16)
+#define FLAG (1 << 17)
+#define NOREQ (1 << 18)
struct dhcp_opt {
uint16_t option;
{ 75, IPV4A, "streettalk_server" },
{ 76, IPV4A, "streettalk_directory_assistance_server" },
{ 77, STRING, "user_class" },
+ { 80, FLAG | NOREQ, "rapid_commit" },
{ 81, STRING | RFC3397, "fqdn_name" },
{ 85, IPV4A, "nds_servers" },
{ 86, STRING, "nds_tree_name" },
p += len;
}
+ if (type == DHCP_DISCOVER &&
+ !(options & DHCPCD_TEST) &&
+ has_option_mask(ifo->requestmask, DHO_RAPIDCOMMIT))
+ {
+ /* RFC 4039 Section 3 */
+ *p++ = DHO_RAPIDCOMMIT;
+ *p++ = 0;
+ }
+
if (type == DHCP_DISCOVER && ifo->options & DHCPCD_REQUEST)
PUTADDR(DHO_IPADDRESS, ifo->req_addr);
if (!(opt->type & REQUEST ||
has_option_mask(ifo->requestmask, opt->option)))
continue;
+ if (opt->type & NOREQ)
+ continue;
if (type == DHCP_INFORM &&
(opt->option == DHO_RENEWALTIME ||
opt->option == DHO_REBINDTIME))
get_option_uint8(&tmp, dhcp, i) != 0)
{
/* If we are bootp, then ignore the need for serverid.
- * To ignore bootp, require dhcp_message_type instead. */
+ * To ignore bootp, require dhcp_message_type. */
if (type == 0 && i == DHO_SERVERID)
continue;
log_dhcp(LOG_WARNING, "reject DHCP", iface, dhcp, from);
DHO_VENDORCLASSID = 60,
DHO_CLIENTID = 61,
DHO_USERCLASS = 77, /* RFC 3004 */
+ DHO_RAPIDCOMMIT = 80, /* RFC 4039 */
DHO_FQDN = 81,
DHO_DNSSEARCH = 119, /* RFC 3397 */
DHO_CSR = 121, /* RFC 3442 */
{ D6_OPTION_SERVERID, BINHEX, "server_id" },
{ D6_OPTION_IA_ADDR, IPV6A, "ia_addr" },
{ D6_OPTION_PREFERENCE, UINT8, "preference" },
- { D6_OPTION_RAPID_COMMIT, 0, "rapid_commit" },
{ D6_OPTION_UNICAST, ADDRIPV6, "unicast" },
+ { D6_OPTION_RAPID_COMMIT, FLAG | NOREQ, "rapid_commit" },
{ D6_OPTION_STATUS_CODE, SCODE, "status_code" },
{ D6_OPTION_SIP_SERVERS_NAME, RFC3397, "sip_servers_names" },
{ D6_OPTION_SIP_SERVERS_ADDRESS,IPV6A, "sip_servers_addresses" },
{ DHO_DNSDOMAIN, D6_OPTION_FQDN },
{ DHO_NISSERVER, D6_OPTION_NIS_SERVERS },
{ DHO_NTPSERVER, D6_OPTION_SNTP_SERVERS },
+ { DHO_RAPIDCOMMIT, D6_OPTION_RAPID_COMMIT },
{ DHO_FQDN, D6_OPTION_FQDN },
{ DHO_DNSSEARCH, D6_OPTION_DOMAIN_LIST },
{ 0, 0 }
si = NULL;
if (state->state != DH6S_RELEASE) {
for (opt = dhcp6_opts; opt->option; opt++) {
- if (opt->type & REQUEST ||
- has_option_mask(ifo->requestmask6, opt->option))
+ if (!(opt->type & NOREQ) &&
+ (opt->type & REQUEST ||
+ has_option_mask(ifo->requestmask6, opt->option)))
{
n_options++;
len += sizeof(*u16);
IA = 0;
}
+ if (state->state == DH6S_DISCOVER &&
+ !(options & DHCPCD_TEST) &&
+ has_option_mask(ifo->requestmask6, D6_OPTION_RAPID_COMMIT))
+ len += sizeof(*o);
+
if (m == NULL) {
m = state->new;
ml = state->new_len;
dhcp6_makevendor(o);
#endif
+ if (state->state == DH6S_DISCOVER &&
+ !(options & DHCPCD_TEST) &&
+ has_option_mask(ifo->requestmask6, D6_OPTION_RAPID_COMMIT))
+ {
+ o = D6_NEXT_OPTION(o);
+ o->code = htons(D6_OPTION_RAPID_COMMIT);
+ o->len = 0;
+ }
+
for (l = 0; IA && l < ifo->iaid_len; l++) {
o = D6_NEXT_OPTION(o);
o->code = htons(ifo->ia_type);
o->len = 0;
u16 = (uint16_t *)(void *)D6_OPTION_DATA(o);
for (opt = dhcp6_opts; opt->option; opt++) {
- if (opt->type & REQUEST ||
+ if (!(opt->type & NOREQ) &&
+ (opt->type & REQUEST ||
has_option_mask(ifo->requestmask6,
- opt->option))
+ opt->option)))
{
*u16++ = htons(opt->option);
o->len += sizeof(*u16);
return;
}
break;
+ case DH6S_DISCOVER:
+ if (has_option_mask(ifo->requestmask6,
+ D6_OPTION_RAPID_COMMIT) &&
+ dhcp6_getoption(D6_OPTION_RAPID_COMMIT, r, len))
+ state->state = DH6S_REQUEST;
+ else
+ op = NULL;
case DH6S_REQUEST: /* FALLTHROUGH */
case DH6S_RENEW: /* FALLTHROUGH */
case DH6S_REBIND:
switch(r->type) {
case DHCP6_ADVERTISE:
+ if (state->state == DH6S_REQUEST) /* rapid commit */
+ break;
ap = TAILQ_FIRST(&state->addrs);
syslog(LOG_INFO, "%s: ADV %s from %s",
ifp->name, ap->saddr, sfrom);
#define D6_OPTION_IA_ADDR 5
#define D6_OPTION_PREFERENCE 7
#define D6_OPTION_ELAPSED 8
-#define D6_OPTION_RAPID_COMMIT 9
#define D6_OPTION_UNICAST 12
#define D6_OPTION_STATUS_CODE 13
+#define D6_OPTION_RAPID_COMMIT 14
#define D6_OPTION_VENDOR 16
#define D6_OPTION_SIP_SERVERS_NAME 21
#define D6_OPTION_SIP_SERVERS_ADDRESS 22
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd June 5, 2013
+.Dd June 6, 2013
.Dt DHCPCD 8
.Os
.Sh NAME
.Xr dhcpcd-run-hooks 8 ,
.Xr resolvconf 8
.Sh STANDARDS
-RFC 951, RFC 1534, RFC 2131, RFC 2132, RFC 2855, RFC 3004, RFC 3315,RFC 3361,
-RFC 3633, RFC 3396, RFC 3397, RFC 3442, RFC 3927, RFC 4075, RFC 4361, RFC 4390,
-RFC 4702, RFC 4704, RFC 4861, RFC 4833, RFC 5227, RFC 5969, RFC 6106.
+RFC 951, RFC 1534, RFC 2131, RFC 2132, RFC 2855, RFC 3004, RFC 3315, RFC 3361,
+RFC 3633, RFC 3396, RFC 3397, RFC 3442, RFC 3927, RFC 4039, RFC 4075, RFC 4361,
+RFC 4390, RFC 4702, RFC 4704, RFC 4861, RFC 4833, RFC 5227, RFC 5969, RFC 6106.
.Sh AUTHORS
.An Roy Marples Aq roy@marples.name
.Sh BUGS
# Use the same DUID + IAID as set in DHCPv6 for DHCPv4 ClientID as per RFC4361.
duid
+# Rapid commit support.
+# Safe to enable by default because it requires the equivalent option set
+# on the server to actually work.
+option rapid_commit
+
# A list of options to request from the DHCP server.
option domain_name_servers, domain_name, domain_search, host_name
option classless_static_routes