-/* Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+/* Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
return isc::dhcp::Dhcp4Parser::make_SUB_OPTION_DATA(driver.loc_);
case Parser4Context::PARSER_HOOKS_LIBRARY:
return isc::dhcp::Dhcp4Parser::make_SUB_HOOKS_LIBRARY(driver.loc_);
+ case Parser4Context::PARSER_DHCP_DDNS:
+ return isc::dhcp::Dhcp4Parser::make_SUB_DHCP_DDNS(driver.loc_);
}
}
%}
}
}
+\"enable-updates\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser4Context::DHCP_DDNS:
+ return isc::dhcp::Dhcp4Parser::make_ENABLE_UPDATES(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp4Parser::make_STRING("enable-updates", driver.loc_);
+ }
+}
+
+\"qualifying-suffix\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser4Context::DHCP_DDNS:
+ return isc::dhcp::Dhcp4Parser::make_QUALIFYING_SUFFIX(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp4Parser::make_STRING("qualifying-suffix", driver.loc_);
+ }
+}
+
+\"server-ip\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser4Context::DHCP_DDNS:
+ return isc::dhcp::Dhcp4Parser::make_SERVER_IP(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp4Parser::make_STRING("server-ip", driver.loc_);
+ }
+}
+
+\"server-port\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser4Context::DHCP_DDNS:
+ return isc::dhcp::Dhcp4Parser::make_SERVER_PORT(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp4Parser::make_STRING("server-port", driver.loc_);
+ }
+}
+
+\"sender-ip\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser4Context::DHCP_DDNS:
+ return isc::dhcp::Dhcp4Parser::make_SENDER_IP(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp4Parser::make_STRING("sender-ip", driver.loc_);
+ }
+}
+
+\"sender-port\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser4Context::DHCP_DDNS:
+ return isc::dhcp::Dhcp4Parser::make_SENDER_PORT(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp4Parser::make_STRING("sender-port", driver.loc_);
+ }
+}
+
+\"max-queue-size\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser4Context::DHCP_DDNS:
+ return isc::dhcp::Dhcp4Parser::make_MAX_QUEUE_SIZE(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp4Parser::make_STRING("max-queue-size", driver.loc_);
+ }
+}
+
+\"ncr-protocol\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser4Context::DHCP_DDNS:
+ return isc::dhcp::Dhcp4Parser::make_NCR_PROTOCOL(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp4Parser::make_STRING("ncr-protocol", driver.loc_);
+ }
+}
+
+\"ncr-format\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser4Context::DHCP_DDNS:
+ return isc::dhcp::Dhcp4Parser::make_NCR_FORMAT(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp4Parser::make_STRING("ncr-format", driver.loc_);
+ }
+}
+
+\"always-include-fqdn\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser4Context::DHCP_DDNS:
+ return isc::dhcp::Dhcp4Parser::make_ALWAYS_INCLUDE_FQDN(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp4Parser::make_STRING("always-include-fqdn", driver.loc_);
+ }
+}
+
+\"allow-client-update\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser4Context::DHCP_DDNS:
+ return isc::dhcp::Dhcp4Parser::make_ALLOW_CLIENT_UPDATE(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp4Parser::make_STRING("allow-client-update", driver.loc_);
+ }
+}
+
+\"override-no-update\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser4Context::DHCP_DDNS:
+ return isc::dhcp::Dhcp4Parser::make_OVERRIDE_NO_UPDATE(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp4Parser::make_STRING("override-no-update", driver.loc_);
+ }
+}
+
+\"override-client-update\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser4Context::DHCP_DDNS:
+ return isc::dhcp::Dhcp4Parser::make_OVERRIDE_CLIENT_UPDATE(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp4Parser::make_STRING("override-client-update", driver.loc_);
+ }
+}
+
+\"replace-client-name\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser4Context::DHCP_DDNS:
+ return isc::dhcp::Dhcp4Parser::make_REPLACE_CLIENT_NAME(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp4Parser::make_STRING("replace-client-name", driver.loc_);
+ }
+}
+
+\"generated-prefix\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser4Context::DHCP_DDNS:
+ return isc::dhcp::Dhcp4Parser::make_GENERATED_PREFIX(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp4Parser::make_STRING("generated-prefix", driver.loc_);
+ }
+}
+
+(?i:\"UDP\") {
+ /* dhcp-ddns value keywords are case insensitive */
+ if (driver.ctx_ == isc::dhcp::Parser4Context::NCR_PROTOCOL) {
+ return isc::dhcp::Dhcp4Parser::make_UDP(driver.loc_);
+ }
+ std::string tmp(yytext+1);
+ tmp.resize(tmp.size() - 1);
+ return isc::dhcp::Dhcp4Parser::make_STRING(tmp, driver.loc_);
+}
+
+(?i:\"TCP\") {
+ /* dhcp-ddns value keywords are case insensitive */
+ if (driver.ctx_ == isc::dhcp::Parser4Context::NCR_PROTOCOL) {
+ return isc::dhcp::Dhcp4Parser::make_TCP(driver.loc_);
+ }
+ std::string tmp(yytext+1);
+ tmp.resize(tmp.size() - 1);
+ return isc::dhcp::Dhcp4Parser::make_STRING(tmp, driver.loc_);
+}
+
+(?i:\"JSON\") {
+ /* dhcp-ddns value keywords are case insensitive */
+ if (driver.ctx_ == isc::dhcp::Parser4Context::NCR_FORMAT) {
+ return isc::dhcp::Dhcp4Parser::make_JSON(driver.loc_);
+ }
+ std::string tmp(yytext+1);
+ tmp.resize(tmp.size() - 1);
+ return isc::dhcp::Dhcp4Parser::make_STRING(tmp, driver.loc_);
+}
+
+(?i:\"when-present\") {
+ /* dhcp-ddns value keywords are case insensitive */
+ if (driver.ctx_ == isc::dhcp::Parser4Context::REPLACE_CLIENT_NAME) {
+ return isc::dhcp::Dhcp4Parser::make_WHEN_PRESENT(driver.loc_);
+ }
+ std::string tmp(yytext+1);
+ tmp.resize(tmp.size() - 1);
+ return isc::dhcp::Dhcp4Parser::make_STRING(tmp, driver.loc_);
+}
+
+(?i:\"true\") {
+ /* dhcp-ddns value keywords are case insensitive */
+ if (driver.ctx_ == isc::dhcp::Parser4Context::REPLACE_CLIENT_NAME) {
+ return isc::dhcp::Dhcp4Parser::make_WHEN_PRESENT(driver.loc_);
+ }
+ std::string tmp(yytext+1);
+ tmp.resize(tmp.size() - 1);
+ return isc::dhcp::Dhcp4Parser::make_STRING(tmp, driver.loc_);
+}
+
+(?i:\"never\") {
+ /* dhcp-ddns value keywords are case insensitive */
+ if (driver.ctx_ == isc::dhcp::Parser4Context::REPLACE_CLIENT_NAME) {
+ return isc::dhcp::Dhcp4Parser::make_NEVER(driver.loc_);
+ }
+ std::string tmp(yytext+1);
+ tmp.resize(tmp.size() - 1);
+ return isc::dhcp::Dhcp4Parser::make_STRING(tmp, driver.loc_);
+}
+
+(?i:\"false\") {
+ /* dhcp-ddns value keywords are case insensitive */
+ if (driver.ctx_ == isc::dhcp::Parser4Context::REPLACE_CLIENT_NAME) {
+ return isc::dhcp::Dhcp4Parser::make_NEVER(driver.loc_);
+ }
+ std::string tmp(yytext+1);
+ tmp.resize(tmp.size() - 1);
+ return isc::dhcp::Dhcp4Parser::make_STRING(tmp, driver.loc_);
+}
+
+(?i:\"always\") {
+ /* dhcp-ddns value keywords are case insensitive */
+ if (driver.ctx_ == isc::dhcp::Parser4Context::REPLACE_CLIENT_NAME) {
+ return isc::dhcp::Dhcp4Parser::make_ALWAYS(driver.loc_);
+ }
+ std::string tmp(yytext+1);
+ tmp.resize(tmp.size() - 1);
+ return isc::dhcp::Dhcp4Parser::make_STRING(tmp, driver.loc_);
+}
+
+(?i:\"when-not-present\") {
+ /* dhcp-ddns value keywords are case insensitive */
+ if (driver.ctx_ == isc::dhcp::Parser4Context::REPLACE_CLIENT_NAME) {
+ return isc::dhcp::Dhcp4Parser::make_WHEN_NOT_PRESENT(driver.loc_);
+ }
+ std::string tmp(yytext+1);
+ tmp.resize(tmp.size() - 1);
+ return isc::dhcp::Dhcp4Parser::make_STRING(tmp, driver.loc_);
+}
+
\"Dhcp6\" {
switch(driver.ctx_) {
case isc::dhcp::Parser4Context::CONFIG:
-/* Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+/* Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
SOCKET_NAME "socket-name"
DHCP_DDNS "dhcp-ddns"
-
- /// @todo: Implement proper parsing for those parameters in Dhcp4/dhcp-ddns/*.
- /// This should be part of the #5043 ticket. Listing the keywords here for
- /// completeness.
-
- // These are tokens defined in Dhcp4/dhcp-ddns/*
- // They're not
- // ENABLE_UPDATES "enable-updates"
- // SERVER_IP "server-ip"
- // SENDER_IP "sender-ip"
- // SENDER_PORT "sender-port"
- // MAX_QUEUE_SIZE "max-queue-size"
- // NCR_PROTOCOL "ncr-protocol"
- // NCR_FORMAT "ncr-format"
- // ALWAYS_INCLUDE_FQDN "always-include-fqdn"
- // OVERRDIDE_NO_UPDATE "override-no-update"
- // OVERRDIDE_CLIENT_UPDATE "override-client-update"
- // REPLACE_CLIENT_NAME "replace-client-name"
- // GENERATED_PREFIX "generated-prefix"
- // QUALIFYING_SUFFIX "qualifying-suffix"
+ ENABLE_UPDATES "enable-updates"
+ QUALIFYING_SUFFIX "qualifying-suffix"
+ SERVER_IP "server-ip"
+ SERVER_PORT "server-port"
+ SENDER_IP "sender-ip"
+ SENDER_PORT "sender-port"
+ MAX_QUEUE_SIZE "max-queue-size"
+ NCR_PROTOCOL "ncr-protocol"
+ NCR_FORMAT "ncr-format"
+ ALWAYS_INCLUDE_FQDN "always-include-fqdn"
+ ALLOW_CLIENT_UPDATE "allow-client-update"
+ OVERRIDE_NO_UPDATE "override-no-update"
+ OVERRIDE_CLIENT_UPDATE "override-client-update"
+ REPLACE_CLIENT_NAME "replace-client-name"
+ GENERATED_PREFIX "generated-prefix"
+ UDP "UDP"
+ TCP "TCP"
+ JSON "JSON"
+ WHEN_PRESENT "when-present"
+ NEVER "never"
+ ALWAYS "always"
+ WHEN_NOT_PRESENT "when-not-present"
LOGGING "Logging"
LOGGERS "loggers"
SUB_OPTION_DEF
SUB_OPTION_DATA
SUB_HOOKS_LIBRARY
+ SUB_DHCP_DDNS
;
%token <std::string> STRING "constant string"
%token <bool> BOOLEAN "boolean"
%type <ElementPtr> value
+%type <ElementPtr> ncr_protocol_value
+%type <ElementPtr> replace_client_name_value
%printer { yyoutput << $$; } <*>;
| SUB_OPTION_DEF { ctx.ctx_ = ctx.OPTION_DEF; } sub_option_def
| SUB_OPTION_DATA { ctx.ctx_ = ctx.OPTION_DATA; } sub_option_data
| SUB_HOOKS_LIBRARY { ctx.ctx_ = ctx.HOOKS_LIBRARIES; } sub_hooks_library
+ | SUB_DHCP_DDNS { ctx.ctx_ = ctx.DHCP_DDNS; } sub_dhcp_ddns
;
// ---- generic JSON parser ---------------------------------
ElementPtr m(new MapElement(ctx.loc2pos(@1)));
ctx.stack_.back()->set("dhcp-ddns", m);
ctx.stack_.push_back(m);
- ctx.enter(ctx.NO_KEYWORD);
-} COLON LCURLY_BRACKET not_empty_map RCURLY_BRACKET {
+ ctx.enter(ctx.DHCP_DDNS);
+} COLON LCURLY_BRACKET dhcp_ddns_params RCURLY_BRACKET {
ctx.stack_.pop_back();
ctx.leave();
};
+sub_dhcp_ddns: LCURLY_BRACKET {
+ // Parse the dhcp-ddns map
+ ElementPtr m(new MapElement(ctx.loc2pos(@1)));
+ ctx.stack_.push_back(m);
+} dhcp_ddns_params RCURLY_BRACKET {
+ // parsing completed
+};
+
+dhcp_ddns_params: dhcp_ddns_param
+ | dhcp_ddns_params COMMA dhcp_ddns_param
+ ;
+
+dhcp_ddns_param: enable_updates
+ | qualifying_suffix
+ | server_ip
+ | server_port
+ | sender_ip
+ | sender_port
+ | max_queue_size
+ | ncr_protocol
+ | ncr_format
+ | always_include_fqdn
+ | allow_client_update
+ | override_no_update
+ | override_client_update
+ | replace_client_name
+ | generated_prefix
+ | unknown_map_entry
+ ;
+
+enable_updates: ENABLE_UPDATES COLON BOOLEAN {
+ ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
+ ctx.stack_.back()->set("enable-updates", b);
+};
+
+qualifying_suffix: QUALIFYING_SUFFIX {
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+ ElementPtr s(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("qualifying-suffix", s);
+ ctx.leave();
+};
+
+server_ip: SERVER_IP {
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+ ElementPtr s(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("server-ip", s);
+ ctx.leave();
+};
+
+server_port: SERVER_PORT COLON INTEGER {
+ ElementPtr i(new IntElement($3, ctx.loc2pos(@3)));
+ ctx.stack_.back()->set("server-port", i);
+};
+
+sender_ip: SENDER_IP {
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+ ElementPtr s(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("sender-ip", s);
+ ctx.leave();
+};
+
+sender_port: SENDER_PORT COLON INTEGER {
+ ElementPtr i(new IntElement($3, ctx.loc2pos(@3)));
+ ctx.stack_.back()->set("sender-port", i);
+};
+
+max_queue_size: MAX_QUEUE_SIZE COLON INTEGER {
+ ElementPtr i(new IntElement($3, ctx.loc2pos(@3)));
+ ctx.stack_.back()->set("max-queue-size", i);
+};
+
+ncr_protocol: NCR_PROTOCOL {
+ ctx.enter(ctx.NCR_PROTOCOL);
+} COLON ncr_protocol_value {
+ ctx.stack_.back()->set("ncr-protocol", $4);
+ ctx.leave();
+};
+
+ncr_protocol_value:
+ UDP { $$ = ElementPtr(new StringElement("UDP", ctx.loc2pos(@1))); }
+ | TCP { $$ = ElementPtr(new StringElement("TCP", ctx.loc2pos(@1))); }
+ ;
+
+ncr_format: NCR_FORMAT {
+ ctx.enter(ctx.NCR_FORMAT);
+} COLON JSON {
+ ElementPtr json(new StringElement("JSON", ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("ncr-format", json);
+ ctx.leave();
+};
+
+always_include_fqdn: ALWAYS_INCLUDE_FQDN COLON BOOLEAN {
+ ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
+ ctx.stack_.back()->set("always-include-fqdn", b);
+};
+
+allow_client_update: ALLOW_CLIENT_UPDATE COLON BOOLEAN {
+ ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
+ ctx.stack_.back()->set("allow-client-update", b);
+};
+
+override_no_update: OVERRIDE_NO_UPDATE COLON BOOLEAN {
+ ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
+ ctx.stack_.back()->set("override-no-update", b);
+};
+
+override_client_update: OVERRIDE_CLIENT_UPDATE COLON BOOLEAN {
+ ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
+ ctx.stack_.back()->set("override-client-update", b);
+};
+
+replace_client_name: REPLACE_CLIENT_NAME {
+ ctx.enter(ctx.REPLACE_CLIENT_NAME);
+} COLON replace_client_name_value {
+ ctx.stack_.back()->set("replace-client-name", $4);
+ ctx.leave();
+};
+
+replace_client_name_value:
+ WHEN_PRESENT {
+ $$ = ElementPtr(new StringElement("when-present", ctx.loc2pos(@1)));
+ }
+ | NEVER {
+ $$ = ElementPtr(new StringElement("never", ctx.loc2pos(@1)));
+ }
+ | ALWAYS {
+ $$ = ElementPtr(new StringElement("always", ctx.loc2pos(@1)));
+ }
+ | WHEN_NOT_PRESENT {
+ $$ = ElementPtr(new StringElement("when-not-present", ctx.loc2pos(@1)));
+ }
+ | BOOLEAN {
+ error(@1, "boolean values for the replace-client-name are "
+ "no longer supported");
+ }
+ ;
+
+generated_prefix: GENERATED_PREFIX {
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+ ElementPtr s(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("generated-prefix", s);
+ ctx.leave();
+};
+
// JSON entries for Dhcp4 and DhcpDdns
dhcp6_json_object: DHCP6 {
}
if (config_pair.first == "dhcp-ddns") {
- // Apply defaults if not in short cut
- if (!!D2ClientConfigParser::isShortCutDisabled(config_pair.second)) {
- D2ClientConfigParser::setAllDefaults(config_pair.second);
- }
+ // Apply defaults if not in short cut
+ if (!D2ClientConfigParser::isShortCutDisabled(config_pair.second)) {
+ D2ClientConfigParser::setAllDefaults(config_pair.second);
+ }
D2ClientConfigParser parser;
D2ClientConfigPtr cfg = parser.parse(config_pair.second);
CfgMgr::instance().getStagingCfg()->setD2ClientConfig(cfg);
return ("output-options");
case DHCP_DDNS:
return ("dhcp-ddns");
+ case NCR_PROTOCOL:
+ return ("ncr-protocol");
+ case NCR_FORMAT:
+ return ("ncr-format");
+ case REPLACE_CLIENT_NAME:
+ return ("replace-client-name");
default:
return ("__unknown__");
}
///< Used while parsing content of Dhcp4.
DHCP4,
- // not yet DHCP6,
+ // not yet Dhcp6, DhcpDdns,
///< Used while parsing content of Logging
LOGGING,
/// Used while parsing Logging/loggers/output_options structures.
OUTPUT_OPTIONS,
- /// Used while parsing Dhcp4/dhcp-ddns
- DHCP_DDNS
+ /// Used while parsing Dhcp4/dhcp-ddns.
+ DHCP_DDNS,
+
+ /// Used while parsing Dhcp4/dhcp-ddns/ncr-protocol
+ NCR_PROTOCOL,
+
+ /// Used while parsing Dhcp4/dhcp-ddns/ncr-format
+ NCR_FORMAT,
+
+ /// Used while parsing Dhcp4/dhcp-ddns/replace-client-name.
+ REPLACE_CLIENT_NAME
+
} ParserContext;
/// @brief File name
// Convert the JSON string to configuration elements.
ConstElementPtr config;
- ASSERT_NO_THROW(config = parseDHCP4(config_str));
+ ASSERT_NO_THROW(config = parseDHCP4(config_str, true));
// Pass the configuration in for parsing.
EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, config));
}
if (config_pair.first == "dhcp-ddns") {
- // Apply defaults if not in short cut
- if (!!D2ClientConfigParser::isShortCutDisabled(config_pair.second)) {
- D2ClientConfigParser::setAllDefaults(config_pair.second);
- }
+ // Apply defaults if not in short cut
+ if (!D2ClientConfigParser::isShortCutDisabled(config_pair.second)) {
+ D2ClientConfigParser::setAllDefaults(config_pair.second);
+ }
D2ClientConfigParser parser;
D2ClientConfigPtr cfg = parser.parse(config_pair.second);
CfgMgr::instance().getStagingCfg()->setD2ClientConfig(cfg);
current_param = "generated-prefix";
generated_prefix = getString(client_config, current_param);
- current_param = "qualifying-suffix";
- qualifying_suffix = getString(client_config, current_param);
+ // temporary fix
+ try {
+ current_param = "qualifying-suffix";
+ qualifying_suffix = getString(client_config, current_param);
+ } catch (const std::exception&) {
+ if (enable_updates) throw;
+ }
} catch (const std::exception& ex) {
isc_throw(D2ClientError, "D2ClientConfig error: " << ex.what()
<< " (" << getPosition(current_param, client_config) << ")");