From: Francis Dupont Date: Fri, 13 Jan 2017 19:10:44 +0000 (+0100) Subject: [5033] Ported flex/bison stuff to DHCPv6 X-Git-Tag: trac5112_base~6^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0a30a27a56137f442321402e2f48238de707ae6e;p=thirdparty%2Fkea.git [5033] Ported flex/bison stuff to DHCPv6 --- diff --git a/src/bin/dhcp6/dhcp6_lexer.ll b/src/bin/dhcp6/dhcp6_lexer.ll index 47235057da..5a5578d45a 100644 --- a/src/bin/dhcp6/dhcp6_lexer.ll +++ b/src/bin/dhcp6/dhcp6_lexer.ll @@ -1,4 +1,4 @@ -/* 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 @@ -123,6 +123,8 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} return isc::dhcp::Dhcp6Parser::make_SUB_OPTION_DATA(driver.loc_); case Parser6Context::PARSER_HOOKS_LIBRARY: return isc::dhcp::Dhcp6Parser::make_SUB_HOOKS_LIBRARY(driver.loc_); + case Parser6Context::PARSER_DHCP_DDNS: + return isc::dhcp::Dhcp6Parser::make_SUB_DHCP_DDNS(driver.loc_); } } %} @@ -171,6 +173,231 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} } +\"enable-updates\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::DHCP_DDNS: + return isc::dhcp::Dhcp6Parser::make_ENABLE_UPDATES(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("enable-updates", driver.loc_); + } +} + +\"qualifying-suffix\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::DHCP_DDNS: + return isc::dhcp::Dhcp6Parser::make_QUALIFYING_SUFFIX(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("qualifying-suffix", driver.loc_); + } +} + +\"server-ip\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::DHCP_DDNS: + return isc::dhcp::Dhcp6Parser::make_SERVER_IP(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("server-ip", driver.loc_); + } +} + +\"server-port\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::DHCP_DDNS: + return isc::dhcp::Dhcp6Parser::make_SERVER_PORT(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("server-port", driver.loc_); + } +} + +\"sender-ip\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::DHCP_DDNS: + return isc::dhcp::Dhcp6Parser::make_SENDER_IP(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("sender-ip", driver.loc_); + } +} + +\"sender-port\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::DHCP_DDNS: + return isc::dhcp::Dhcp6Parser::make_SENDER_PORT(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("sender-port", driver.loc_); + } +} + +\"max-queue-size\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::DHCP_DDNS: + return isc::dhcp::Dhcp6Parser::make_MAX_QUEUE_SIZE(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("max-queue-size", driver.loc_); + } +} + +\"ncr-protocol\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::DHCP_DDNS: + return isc::dhcp::Dhcp6Parser::make_NCR_PROTOCOL(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("ncr-protocol", driver.loc_); + } +} + +\"ncr-format\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::DHCP_DDNS: + return isc::dhcp::Dhcp6Parser::make_NCR_FORMAT(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("ncr-format", driver.loc_); + } +} + +\"always-include-fqdn\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::DHCP_DDNS: + return isc::dhcp::Dhcp6Parser::make_ALWAYS_INCLUDE_FQDN(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("always-include-fqdn", driver.loc_); + } +} + +\"allow-client-update\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::DHCP_DDNS: + return isc::dhcp::Dhcp6Parser::make_ALLOW_CLIENT_UPDATE(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("allow-client-update", driver.loc_); + } +} + +\"override-no-update\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::DHCP_DDNS: + return isc::dhcp::Dhcp6Parser::make_OVERRIDE_NO_UPDATE(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("override-no-update", driver.loc_); + } +} + +\"override-client-update\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::DHCP_DDNS: + return isc::dhcp::Dhcp6Parser::make_OVERRIDE_CLIENT_UPDATE(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("override-client-update", driver.loc_); + } +} + +\"replace-client-name\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::DHCP_DDNS: + return isc::dhcp::Dhcp6Parser::make_REPLACE_CLIENT_NAME(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("replace-client-name", driver.loc_); + } +} + +\"generated-prefix\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::DHCP_DDNS: + return isc::dhcp::Dhcp6Parser::make_GENERATED_PREFIX(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("generated-prefix", driver.loc_); + } +} + +(?i:\"UDP\") { + /* dhcp-ddns value keywords are case insensitive */ + if (driver.ctx_ == isc::dhcp::Parser6Context::NCR_PROTOCOL) { + return isc::dhcp::Dhcp6Parser::make_UDP(driver.loc_); + } + std::string tmp(yytext+1); + tmp.resize(tmp.size() - 1); + return isc::dhcp::Dhcp6Parser::make_STRING(tmp, driver.loc_); +} + +(?i:\"TCP\") { + /* dhcp-ddns value keywords are case insensitive */ + if (driver.ctx_ == isc::dhcp::Parser6Context::NCR_PROTOCOL) { + return isc::dhcp::Dhcp6Parser::make_TCP(driver.loc_); + } + std::string tmp(yytext+1); + tmp.resize(tmp.size() - 1); + return isc::dhcp::Dhcp6Parser::make_STRING(tmp, driver.loc_); +} + +(?i:\"JSON\") { + /* dhcp-ddns value keywords are case insensitive */ + if (driver.ctx_ == isc::dhcp::Parser6Context::NCR_FORMAT) { + return isc::dhcp::Dhcp6Parser::make_JSON(driver.loc_); + } + std::string tmp(yytext+1); + tmp.resize(tmp.size() - 1); + return isc::dhcp::Dhcp6Parser::make_STRING(tmp, driver.loc_); +} + +(?i:\"when-present\") { + /* dhcp-ddns value keywords are case insensitive */ + if (driver.ctx_ == isc::dhcp::Parser6Context::REPLACE_CLIENT_NAME) { + return isc::dhcp::Dhcp6Parser::make_WHEN_PRESENT(driver.loc_); + } + std::string tmp(yytext+1); + tmp.resize(tmp.size() - 1); + return isc::dhcp::Dhcp6Parser::make_STRING(tmp, driver.loc_); +} + +(?i:\"true\") { + /* dhcp-ddns value keywords are case insensitive */ + if (driver.ctx_ == isc::dhcp::Parser6Context::REPLACE_CLIENT_NAME) { + return isc::dhcp::Dhcp6Parser::make_WHEN_PRESENT(driver.loc_); + } + std::string tmp(yytext+1); + tmp.resize(tmp.size() - 1); + return isc::dhcp::Dhcp6Parser::make_STRING(tmp, driver.loc_); +} + +(?i:\"never\") { + /* dhcp-ddns value keywords are case insensitive */ + if (driver.ctx_ == isc::dhcp::Parser6Context::REPLACE_CLIENT_NAME) { + return isc::dhcp::Dhcp6Parser::make_NEVER(driver.loc_); + } + std::string tmp(yytext+1); + tmp.resize(tmp.size() - 1); + return isc::dhcp::Dhcp6Parser::make_STRING(tmp, driver.loc_); +} + +(?i:\"false\") { + /* dhcp-ddns value keywords are case insensitive */ + if (driver.ctx_ == isc::dhcp::Parser6Context::REPLACE_CLIENT_NAME) { + return isc::dhcp::Dhcp6Parser::make_NEVER(driver.loc_); + } + std::string tmp(yytext+1); + tmp.resize(tmp.size() - 1); + return isc::dhcp::Dhcp6Parser::make_STRING(tmp, driver.loc_); +} + +(?i:\"always\") { + /* dhcp-ddns value keywords are case insensitive */ + if (driver.ctx_ == isc::dhcp::Parser6Context::REPLACE_CLIENT_NAME) { + return isc::dhcp::Dhcp6Parser::make_ALWAYS(driver.loc_); + } + std::string tmp(yytext+1); + tmp.resize(tmp.size() - 1); + return isc::dhcp::Dhcp6Parser::make_STRING(tmp, driver.loc_); +} + +(?i:\"when-not-present\") { + /* dhcp-ddns value keywords are case insensitive */ + if (driver.ctx_ == isc::dhcp::Parser6Context::REPLACE_CLIENT_NAME) { + return isc::dhcp::Dhcp6Parser::make_WHEN_NOT_PRESENT(driver.loc_); + } + std::string tmp(yytext+1); + tmp.resize(tmp.size() - 1); + return isc::dhcp::Dhcp6Parser::make_STRING(tmp, driver.loc_); +} + \"Dhcp6\" { switch(driver.ctx_) { case isc::dhcp::Parser6Context::CONFIG: diff --git a/src/bin/dhcp6/dhcp6_parser.yy b/src/bin/dhcp6/dhcp6_parser.yy index d3a460ace7..d6672013ff 100644 --- a/src/bin/dhcp6/dhcp6_parser.yy +++ b/src/bin/dhcp6/dhcp6_parser.yy @@ -1,4 +1,4 @@ -/* 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 @@ -133,26 +133,28 @@ using namespace std; SOCKET_NAME "socket-name" DHCP_DDNS "dhcp-ddns" - - /// @todo: Implement proper parsing for those parameters in Dhcp6/dhcp-ddns/*. - /// This should be part of the #5043 ticket. Listing the keywords here for - /// completeness. - - // These are tokens defined in Dhcp6/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" @@ -177,6 +179,7 @@ using namespace std; SUB_OPTION_DEF SUB_OPTION_DATA SUB_HOOKS_LIBRARY + SUB_DHCP_DDNS ; %token STRING "constant string" @@ -185,6 +188,8 @@ using namespace std; %token BOOLEAN "boolean" %type value +%type ncr_protocol_value +%type replace_client_name_value %printer { yyoutput << $$; } <*>; @@ -206,6 +211,7 @@ start: TOPLEVEL_JSON { ctx.ctx_ = ctx.NO_KEYWORD; } sub_json | 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 --------------------------------- @@ -1409,12 +1415,160 @@ dhcp_ddns: DHCP_DDNS { 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 dhcp4_json_object: DHCP4 { diff --git a/src/bin/dhcp6/parser_context.cc b/src/bin/dhcp6/parser_context.cc index cd90fefc76..11d10e7a35 100644 --- a/src/bin/dhcp6/parser_context.cc +++ b/src/bin/dhcp6/parser_context.cc @@ -165,6 +165,12 @@ Parser6Context::contextName() 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__"); } diff --git a/src/bin/dhcp6/parser_context.h b/src/bin/dhcp6/parser_context.h index 9a1ae41956..7d2263a66f 100644 --- a/src/bin/dhcp6/parser_context.h +++ b/src/bin/dhcp6/parser_context.h @@ -190,7 +190,7 @@ public: ///< Used while parsing content of Dhcp6. DHCP6, - // not yet DHCP4, + // not yet Dhcp4, DhcpDdns, ///< Used while parsing content of Logging LOGGING, @@ -254,8 +254,18 @@ public: /// Used while parsing Logging/loggers/output_options structures. OUTPUT_OPTIONS, - /// Used while parsing Dhcp6/dhcp-ddns - DHCP_DDNS + /// Used while parsing Dhcp6/dhcp-ddns. + DHCP_DDNS, + + /// Used while parsing Dhcp6/dhcp-ddns/ncr-protocol + NCR_PROTOCOL, + + /// Used while parsing Dhcp6/dhcp-ddns/ncr-format + NCR_FORMAT, + + /// Used while parsing Dhcp6/dhcp-ddns/replace-client-name. + REPLACE_CLIENT_NAME + } ParserContext; /// @brief File name diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc index 43cb865973..cd96a25d0d 100644 --- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc +++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc @@ -276,7 +276,7 @@ TEST_F(Dhcpv6SrvTest, DUID) { case DUID::DUID_LLT: { // DUID must contain at least 6 bytes long MAC // + 8 bytes of fixed header - EXPECT_GE(14, len); + EXPECT_GE(len, 14); uint16_t hw_type = data.readUint16(); // there's no real way to find out "correct"