Browse Source

[5033] Setup flex/bison (checkpoint - only DHCPv4 done)

Francis Dupont 8 years ago
parent
commit
5b165e3ceb

+ 228 - 1
src/bin/dhcp4/dhcp4_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
    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
    License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -121,6 +121,8 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
             return isc::dhcp::Dhcp4Parser::make_SUB_OPTION_DATA(driver.loc_);
             return isc::dhcp::Dhcp4Parser::make_SUB_OPTION_DATA(driver.loc_);
         case Parser4Context::PARSER_HOOKS_LIBRARY:
         case Parser4Context::PARSER_HOOKS_LIBRARY:
             return isc::dhcp::Dhcp4Parser::make_SUB_HOOKS_LIBRARY(driver.loc_);
             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_);
         }
         }
     }
     }
 %}
 %}
@@ -815,6 +817,231 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
     }
     }
 }
 }
 
 
+\"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\"  {
 \"Dhcp6\"  {
     switch(driver.ctx_) {
     switch(driver.ctx_) {
     case isc::dhcp::Parser4Context::CONFIG:
     case isc::dhcp::Parser4Context::CONFIG:

+ 177 - 23
src/bin/dhcp4/dhcp4_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
    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
    License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -134,26 +134,28 @@ using namespace std;
   SOCKET_NAME "socket-name"
   SOCKET_NAME "socket-name"
 
 
   DHCP_DDNS "dhcp-ddns"
   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"
   LOGGING "Logging"
   LOGGERS "loggers"
   LOGGERS "loggers"
@@ -177,6 +179,7 @@ using namespace std;
   SUB_OPTION_DEF
   SUB_OPTION_DEF
   SUB_OPTION_DATA
   SUB_OPTION_DATA
   SUB_HOOKS_LIBRARY
   SUB_HOOKS_LIBRARY
+  SUB_DHCP_DDNS
 ;
 ;
 
 
 %token <std::string> STRING "constant string"
 %token <std::string> STRING "constant string"
@@ -185,6 +188,8 @@ using namespace std;
 %token <bool> BOOLEAN "boolean"
 %token <bool> BOOLEAN "boolean"
 
 
 %type <ElementPtr> value
 %type <ElementPtr> value
+%type <ElementPtr> ncr_protocol_value
+%type <ElementPtr> replace_client_name_value
 
 
 %printer { yyoutput << $$; } <*>;
 %printer { yyoutput << $$; } <*>;
 
 
@@ -205,6 +210,7 @@ start: TOPLEVEL_JSON { ctx.ctx_ = ctx.NO_KEYWORD; } sub_json
      | SUB_OPTION_DEF { ctx.ctx_ = ctx.OPTION_DEF; } sub_option_def
      | SUB_OPTION_DEF { ctx.ctx_ = ctx.OPTION_DEF; } sub_option_def
      | SUB_OPTION_DATA { ctx.ctx_ = ctx.OPTION_DATA; } sub_option_data
      | SUB_OPTION_DATA { ctx.ctx_ = ctx.OPTION_DATA; } sub_option_data
      | SUB_HOOKS_LIBRARY { ctx.ctx_ = ctx.HOOKS_LIBRARIES; } sub_hooks_library
      | 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 ---------------------------------
 // ---- generic JSON parser ---------------------------------
@@ -1389,12 +1395,160 @@ dhcp_ddns: DHCP_DDNS {
     ElementPtr m(new MapElement(ctx.loc2pos(@1)));
     ElementPtr m(new MapElement(ctx.loc2pos(@1)));
     ctx.stack_.back()->set("dhcp-ddns", m);
     ctx.stack_.back()->set("dhcp-ddns", m);
     ctx.stack_.push_back(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.stack_.pop_back();
     ctx.leave();
     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
 // JSON entries for Dhcp4 and DhcpDdns
 
 
 dhcp6_json_object: DHCP6 {
 dhcp6_json_object: DHCP6 {

+ 4 - 4
src/bin/dhcp4/json_config_parser.cc

@@ -637,10 +637,10 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
             }
             }
 
 
             if (config_pair.first == "dhcp-ddns") {
             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;
                 D2ClientConfigParser parser;
                 D2ClientConfigPtr cfg = parser.parse(config_pair.second);
                 D2ClientConfigPtr cfg = parser.parse(config_pair.second);
                 CfgMgr::instance().getStagingCfg()->setD2ClientConfig(cfg);
                 CfgMgr::instance().getStagingCfg()->setD2ClientConfig(cfg);

+ 6 - 0
src/bin/dhcp4/parser_context.cc

@@ -161,6 +161,12 @@ Parser4Context::contextName()
         return ("output-options");
         return ("output-options");
     case DHCP_DDNS:
     case DHCP_DDNS:
         return ("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:
     default:
         return ("__unknown__");
         return ("__unknown__");
     }
     }

+ 13 - 3
src/bin/dhcp4/parser_context.h

@@ -187,7 +187,7 @@ public:
         ///< Used while parsing content of Dhcp4.
         ///< Used while parsing content of Dhcp4.
         DHCP4,
         DHCP4,
 
 
-        // not yet DHCP6,
+        // not yet Dhcp6, DhcpDdns,
 
 
         ///< Used while parsing content of Logging
         ///< Used while parsing content of Logging
         LOGGING,
         LOGGING,
@@ -245,8 +245,18 @@ public:
         /// Used while parsing Logging/loggers/output_options structures.
         /// Used while parsing Logging/loggers/output_options structures.
         OUTPUT_OPTIONS,
         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;
     } ParserContext;
 
 
     /// @brief File name
     /// @brief File name

+ 1 - 1
src/bin/dhcp4/tests/config_parser_unittest.cc

@@ -3301,7 +3301,7 @@ TEST_F(Dhcp4ParserTest, d2ClientConfig) {
 
 
     // Convert the JSON string to configuration elements.
     // Convert the JSON string to configuration elements.
     ConstElementPtr config;
     ConstElementPtr config;
-    ASSERT_NO_THROW(config = parseDHCP4(config_str));
+    ASSERT_NO_THROW(config = parseDHCP4(config_str, true));
 
 
     // Pass the configuration in for parsing.
     // Pass the configuration in for parsing.
     EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, config));
     EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, config));

+ 4 - 4
src/bin/dhcp6/json_config_parser.cc

@@ -911,10 +911,10 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
             }
             }
 
 
             if (config_pair.first == "dhcp-ddns") {
             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;
                 D2ClientConfigParser parser;
                 D2ClientConfigPtr cfg = parser.parse(config_pair.second);
                 D2ClientConfigPtr cfg = parser.parse(config_pair.second);
                 CfgMgr::instance().getStagingCfg()->setD2ClientConfig(cfg);
                 CfgMgr::instance().getStagingCfg()->setD2ClientConfig(cfg);

+ 7 - 2
src/lib/dhcpsrv/parsers/dhcp_parsers.cc

@@ -1333,8 +1333,13 @@ D2ClientConfigParser::parse(isc::data::ConstElementPtr client_config) {
         current_param = "generated-prefix";
         current_param = "generated-prefix";
         generated_prefix = getString(client_config, current_param);
         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) {
     } catch (const std::exception& ex) {
         isc_throw(D2ClientError, "D2ClientConfig error: " << ex.what()
         isc_throw(D2ClientError, "D2ClientConfig error: " << ex.what()
                   << " (" << getPosition(current_param, client_config) << ")");
                   << " (" << getPosition(current_param, client_config) << ")");