summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/dhcp6/dhcp6_lexer.ll126
-rw-r--r--src/bin/dhcp6/dhcp6_parser.yy240
-rw-r--r--src/bin/dhcp6/parser_context.cc6
-rw-r--r--src/bin/dhcp6/parser_context.h3
-rw-r--r--src/bin/dhcp6/tests/config_parser_unittest.cc112
-rw-r--r--src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc2
-rw-r--r--src/bin/dhcp6/tests/dhcp6_srv_unittest.cc4
-rw-r--r--src/bin/dhcp6/tests/dhcp6_test_utils.h4
8 files changed, 368 insertions, 129 deletions
diff --git a/src/bin/dhcp6/dhcp6_lexer.ll b/src/bin/dhcp6/dhcp6_lexer.ll
index 11b32ad252..efc4b62c74 100644
--- a/src/bin/dhcp6/dhcp6_lexer.ll
+++ b/src/bin/dhcp6/dhcp6_lexer.ll
@@ -284,6 +284,7 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
\"preferred-lifetime\" {
switch(driver.ctx_) {
case isc::dhcp::Parser6Context::DHCP6:
+ case isc::dhcp::Parser6Context::SUBNET6:
return isc::dhcp::Dhcp6Parser::make_PREFERRED_LIFETIME(driver.loc_);
default:
return isc::dhcp::Dhcp6Parser::make_STRING("preferred-lifetime", driver.loc_);
@@ -293,6 +294,7 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
\"valid-lifetime\" {
switch(driver.ctx_) {
case isc::dhcp::Parser6Context::DHCP6:
+ case isc::dhcp::Parser6Context::SUBNET6:
return isc::dhcp::Dhcp6Parser::make_VALID_LIFETIME(driver.loc_);
default:
return isc::dhcp::Dhcp6Parser::make_STRING("valid-lifetime", driver.loc_);
@@ -302,6 +304,7 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
\"renew-timer\" {
switch(driver.ctx_) {
case isc::dhcp::Parser6Context::DHCP6:
+ case isc::dhcp::Parser6Context::SUBNET6:
return isc::dhcp::Dhcp6Parser::make_RENEW_TIMER(driver.loc_);
default:
return isc::dhcp::Dhcp6Parser::make_STRING("renew-timer", driver.loc_);
@@ -311,12 +314,22 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
\"rebind-timer\" {
switch(driver.ctx_) {
case isc::dhcp::Parser6Context::DHCP6:
+ case isc::dhcp::Parser6Context::SUBNET6:
return isc::dhcp::Dhcp6Parser::make_REBIND_TIMER(driver.loc_);
default:
return isc::dhcp::Dhcp6Parser::make_STRING("rebind-timer", driver.loc_);
}
}
+\"decline-probation-period\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::DHCP6:
+ return isc::dhcp::Dhcp6Parser::make_DECLINE_PROBATION_PERIOD(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("decline-probation-period", driver.loc_);
+ }
+}
+
\"subnet6\" {
switch(driver.ctx_) {
case isc::dhcp::Parser6Context::DHCP6:
@@ -446,6 +459,15 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
}
}
+\"interface-id\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::SUBNET6:
+ return isc::dhcp::Dhcp6Parser::make_INTERFACE_ID(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("interface-id", driver.loc_);
+ }
+}
+
\"id\" {
switch(driver.ctx_) {
case isc::dhcp::Parser6Context::SUBNET6:
@@ -455,6 +477,24 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
}
}
+\"rapid-commit\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::SUBNET6:
+ return isc::dhcp::Dhcp6Parser::make_RAPID_COMMIT(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("rapid-commit", driver.loc_);
+ }
+}
+
+\"reservation-mode\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::SUBNET6:
+ return isc::dhcp::Dhcp6Parser::make_RESERVATION_MODE(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("reservation-mode", driver.loc_);
+ }
+}
+
\"code\" {
switch(driver.ctx_) {
case isc::dhcp::Parser6Context::OPTION_DEF:
@@ -645,7 +685,6 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
\"csv-format\" {
switch(driver.ctx_) {
- case isc::dhcp::Parser6Context::OPTION_DEF:
case isc::dhcp::Parser6Context::OPTION_DATA:
return isc::dhcp::Dhcp6Parser::make_CSV_FORMAT(driver.loc_);
default:
@@ -653,6 +692,51 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
}
}
+\"record-types\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::OPTION_DEF:
+ return isc::dhcp::Dhcp6Parser::make_RECORD_TYPES(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("record-types", driver.loc_);
+ }
+}
+
+\"encapsulate\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::OPTION_DEF:
+ return isc::dhcp::Dhcp6Parser::make_ENCAPSULATE(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("encapsulate", driver.loc_);
+ }
+}
+
+\"array\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::OPTION_DEF:
+ return isc::dhcp::Dhcp6Parser::make_ARRAY(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("array", driver.loc_);
+ }
+}
+
+\"relay\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::SUBNET6:
+ return isc::dhcp::Dhcp6Parser::make_RELAY(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("relay", driver.loc_);
+ }
+}
+
+\"ip-address\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::RELAY:
+ return isc::dhcp::Dhcp6Parser::make_IP_ADDRESS(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("ip-address", driver.loc_);
+ }
+}
+
\"hooks-libraries\" {
switch(driver.ctx_) {
case isc::dhcp::Parser6Context::DHCP6:
@@ -734,30 +818,48 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
}
}
-\"dhcp-ddns\" {
+\"version\" {
switch(driver.ctx_) {
case isc::dhcp::Parser6Context::DHCP6:
- return isc::dhcp::Dhcp6Parser::make_DHCP_DDNS(driver.loc_);
+ return isc::dhcp::Dhcp6Parser::make_VERSION(driver.loc_);
default:
- return isc::dhcp::Dhcp6Parser::make_STRING("dhcp-ddns", driver.loc_);
+ return isc::dhcp::Dhcp6Parser::make_STRING("version", driver.loc_);
+ }
+}
+
+\"control-socket\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::DHCP6:
+ return isc::dhcp::Dhcp6Parser::make_CONTROL_SOCKET(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("control-socket", driver.loc_);
}
}
-\"enable-updates\" {
+\"socket-type\" {
switch(driver.ctx_) {
- case isc::dhcp::Parser6Context::DHCP_DDNS:
- return isc::dhcp::Dhcp6Parser::make_ENABLE_UPDATES(driver.loc_);
+ case isc::dhcp::Parser6Context::CONTROL_SOCKET:
+ return isc::dhcp::Dhcp6Parser::make_SOCKET_TYPE(driver.loc_);
default:
- return isc::dhcp::Dhcp6Parser::make_STRING("enable-updates", driver.loc_);
+ return isc::dhcp::Dhcp6Parser::make_STRING("socket-type", driver.loc_);
}
}
-\"qualifying-suffix\" {
+\"socket-name\" {
switch(driver.ctx_) {
- case isc::dhcp::Parser6Context::DHCP_DDNS:
- return isc::dhcp::Dhcp6Parser::make_QUALIFYING_SUFFIX(driver.loc_);
+ case isc::dhcp::Parser6Context::CONTROL_SOCKET:
+ return isc::dhcp::Dhcp6Parser::make_SOCKET_NAME(driver.loc_);
default:
- return isc::dhcp::Dhcp6Parser::make_STRING("qualifying-suffix", driver.loc_);
+ return isc::dhcp::Dhcp6Parser::make_STRING("socket-name", driver.loc_);
+ }
+}
+
+\"dhcp-ddns\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::DHCP6:
+ return isc::dhcp::Dhcp6Parser::make_DHCP_DDNS(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("dhcp-ddns", driver.loc_);
}
}
diff --git a/src/bin/dhcp6/dhcp6_parser.yy b/src/bin/dhcp6/dhcp6_parser.yy
index 8b1e3abb5d..33c365cf9b 100644
--- a/src/bin/dhcp6/dhcp6_parser.yy
+++ b/src/bin/dhcp6/dhcp6_parser.yy
@@ -66,6 +66,7 @@ using namespace std;
VALID_LIFETIME "valid-lifetime"
RENEW_TIMER "renew-timer"
REBIND_TIMER "rebind-timer"
+ DECLINE_PROBATION_PERIOD "decline-probation-period"
SUBNET6 "subnet6"
OPTION_DEF "option-def"
OPTION_DATA "option-data"
@@ -74,6 +75,9 @@ using namespace std;
CODE "code"
SPACE "space"
CSV_FORMAT "csv-format"
+ RECORD_TYPES "record-types"
+ ENCAPSULATE "encapsulate"
+ ARRAY "array"
POOLS "pools"
POOL "pool"
@@ -84,7 +88,10 @@ using namespace std;
SUBNET "subnet"
INTERFACE "interface"
+ INTERFACE_ID "interface-id"
ID "id"
+ RAPID_COMMIT "rapid-commit"
+ RESERVATION_MODE "reservation-mode"
MAC_SOURCES "mac-sources"
RELAY_SUPPLIED_OPTIONS "relay-supplied-options"
@@ -101,6 +108,9 @@ using namespace std;
HW_ADDRESS "hw-address"
HOSTNAME "hostname"
+ RELAY "relay"
+ IP_ADDRESS "ip-address"
+
HOOKS_LIBRARIES "hooks-libraries"
LIBRARY "library"
@@ -113,6 +123,13 @@ using namespace std;
ENTERPRISE_ID "enterprise-id"
DHCP4O6_PORT "dhcp4o6-port"
+ VERSION "version"
+
+ CONTROL_SOCKET "control-socket"
+ SOCKET_TYPE "socket-type"
+ SOCKET_NAME "socket-name"
+
+ DHCP_DDNS "dhcp-ddns"
LOGGING "Logging"
LOGGERS "loggers"
@@ -121,10 +138,6 @@ using namespace std;
DEBUGLEVEL "debuglevel"
SEVERITY "severity"
- DHCP_DDNS "dhcp-ddns"
- ENABLE_UPDATES "enable-updates"
- QUALIFYING_SUFFIX "qualifying-suffix"
-
DHCP4 "Dhcp4"
DHCPDDNS "DhcpDdns"
@@ -150,6 +163,7 @@ using namespace std;
%token <bool> BOOLEAN "boolean"
%type <ElementPtr> value
+%type <ElementPtr> version_value
%printer { yyoutput << $$; } <*>;
@@ -324,6 +338,7 @@ global_param: preferred_lifetime
| valid_lifetime
| renew_timer
| rebind_timer
+ | decline_probation_period
| subnet6_list
| interfaces_config
| lease_database
@@ -338,6 +353,8 @@ global_param: preferred_lifetime
| expired_leases_processing
| server_id
| dhcp4o6_port
+ | version
+ | control_socket
| dhcp_ddns
| unknown_map_entry
;
@@ -362,6 +379,11 @@ rebind_timer: REBIND_TIMER COLON INTEGER {
ctx.stack_.back()->set("rebind-timer", prf);
};
+decline_probation_period: DECLINE_PROBATION_PERIOD COLON INTEGER {
+ ElementPtr dpp(new IntElement($3, ctx.loc2pos(@3)));
+ ctx.stack_.back()->set("decline-probation-period", dpp);
+};
+
interfaces_config: INTERFACES_CONFIG {
ElementPtr i(new MapElement(ctx.loc2pos(@1)));
ctx.stack_.back()->set("interfaces-config", i);
@@ -669,14 +691,22 @@ subnet6_params: subnet6_param
;
// This defines a list of allowed parameters for each subnet.
-subnet6_param: option_data_list
+subnet6_param: preferred_lifetime
+ | valid_lifetime
+ | renew_timer
+ | rebind_timer
+ | option_data_list
| pools_list
| pd_pools_list
| subnet
| interface
+ | interface_id
| id
+ | rapid_commit
| client_class
| reservations
+ | reservation_mode
+ | relay
| unknown_map_entry
;
@@ -696,6 +726,14 @@ interface: INTERFACE {
ctx.leave();
};
+interface_id: INTERFACE_ID {
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+ ElementPtr iface(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("interface-id", iface);
+ ctx.leave();
+};
+
client_class: CLIENT_CLASS {
ctx.enter(ctx.CLIENT_CLASS);
} COLON STRING {
@@ -704,11 +742,24 @@ client_class: CLIENT_CLASS {
ctx.leave();
};
+reservation_mode: RESERVATION_MODE {
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+ ElementPtr rm(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("reservation-mode", rm);
+ ctx.leave();
+};
+
id: ID COLON INTEGER {
ElementPtr id(new IntElement($3, ctx.loc2pos(@3)));
ctx.stack_.back()->set("id", id);
};
+rapid_commit: RAPID_COMMIT COLON BOOLEAN {
+ ElementPtr rc(new BoolElement($3, ctx.loc2pos(@3)));
+ ctx.stack_.back()->set("rapid-commit", rc);
+};
+
// ---- option-def --------------------------
// This defines the "option-def": [ ... ] entry that may appear
@@ -764,12 +815,13 @@ not_empty_option_def_params: option_def_param
option_def_param: option_def_name
| option_def_code
| option_def_type
+ | option_def_record_types
| option_def_space
- | option_def_csv_format
+ | option_def_encapsulate
+ | option_def_array
| unknown_map_entry
;
-
option_def_name: name;
code: CODE COLON INTEGER {
@@ -781,6 +833,14 @@ option_def_code: code;
option_def_type: type;
+option_def_record_types: RECORD_TYPES {
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+ ElementPtr rtypes(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("record-types", rtypes);
+ ctx.leave();
+};
+
space: SPACE {
ctx.enter(ctx.NO_KEYWORD);
} COLON STRING {
@@ -791,12 +851,18 @@ space: SPACE {
option_def_space: space;
-csv_format: CSV_FORMAT COLON BOOLEAN {
- ElementPtr space(new BoolElement($3, ctx.loc2pos(@3)));
- ctx.stack_.back()->set("csv-format", space);
+option_def_encapsulate: ENCAPSULATE {
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+ ElementPtr encap(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("encapsulate", encap);
+ ctx.leave();
};
-option_def_csv_format: csv_format;
+option_def_array: ARRAY COLON BOOLEAN {
+ ElementPtr array(new BoolElement($3, ctx.loc2pos(@3)));
+ ctx.stack_.back()->set("array", array);
+};
// ---- option-data --------------------------
@@ -858,7 +924,6 @@ option_data_param: option_data_name
| unknown_map_entry
;
-
option_data_name: name;
option_data_data: DATA {
@@ -873,7 +938,10 @@ option_data_code: code;
option_data_space: space;
-option_data_csv_format: csv_format;
+option_data_csv_format: CSV_FORMAT COLON BOOLEAN {
+ ElementPtr space(new BoolElement($3, ctx.loc2pos(@3)));
+ ctx.stack_.back()->set("csv-format", space);
+};
// ---- pools ------------------------------------
@@ -1111,6 +1179,27 @@ reservation_client_classes: CLIENT_CLASSES {
// --- end of reservations definitions -----------------------
+// --- relay -------------------------------------------------
+relay: RELAY {
+ ElementPtr m(new MapElement(ctx.loc2pos(@1)));
+ ctx.stack_.back()->set("relay", m);
+ ctx.stack_.push_back(m);
+ ctx.enter(ctx.RELAY);
+} COLON LCURLY_BRACKET relay_map RCURLY_BRACKET {
+ ctx.stack_.pop_back();
+ ctx.leave();
+};
+
+relay_map: IP_ADDRESS {
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+ ElementPtr ip(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("ip-address", ip);
+ ctx.leave();
+};
+
+// --- end of relay definitions ------------------------------
+
// --- client classes ----------------------------------------
client_classes: CLIENT_CLASSES {
ElementPtr l(new ListElement(ctx.loc2pos(@1)));
@@ -1158,7 +1247,6 @@ client_class_test: TEST {
ctx.leave();
}
-
// --- end of client classes ---------------------------------
// --- server-id ---------------------------------------------
@@ -1215,6 +1303,84 @@ dhcp4o6_port: DHCP4O6_PORT COLON INTEGER {
ctx.stack_.back()->set("dhcp4o6-port", time);
};
+// code says it is a string, unit test a number
+version: VERSION {
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON version_value {
+ ctx.stack_.back()->set("version", $4);
+ ctx.leave();
+};
+
+version_value:
+ INTEGER { $$ = ElementPtr(new IntElement($1, ctx.loc2pos(@1))); }
+ | FLOAT { $$ = ElementPtr(new DoubleElement($1, ctx.loc2pos(@1))); }
+ | STRING { $$ = ElementPtr(new StringElement($1, ctx.loc2pos(@1))); }
+ ;
+
+// --- control socket ----------------------------------------
+
+control_socket: CONTROL_SOCKET {
+ ElementPtr m(new MapElement(ctx.loc2pos(@1)));
+ ctx.stack_.back()->set("control-socket", m);
+ ctx.stack_.push_back(m);
+ ctx.enter(ctx.CONTROL_SOCKET);
+} COLON LCURLY_BRACKET control_socket_params RCURLY_BRACKET {
+ ctx.stack_.pop_back();
+ ctx.leave();
+};
+
+control_socket_params: control_socket_param
+ | control_socket_params COMMA control_socket_param
+ ;
+
+control_socket_param: socket_type
+ | socket_name
+ ;
+
+socket_type: SOCKET_TYPE {
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+ ElementPtr stype(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("socket-type", stype);
+ ctx.leave();
+};
+
+socket_name: SOCKET_NAME {
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+ ElementPtr name(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("socket-name", name);
+ ctx.leave();
+};
+
+// --- dhcp ddns ---------------------------------------------
+
+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.stack_.pop_back();
+ ctx.leave();
+};
+
+// JSON entries for Dhcp4 and DhcpDdns
+
+dhcp4_json_object: DHCP4 {
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON value {
+ ctx.stack_.back()->set("Dhcp4", $4);
+ ctx.leave();
+};
+
+dhcpddns_json_object: DHCPDDNS {
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON value {
+ ctx.stack_.back()->set("DhcpDdns", $4);
+ ctx.leave();
+};
+
// --- logging entry -----------------------------------------
// This defines the top level "Logging" object. It parses
@@ -1324,52 +1490,6 @@ output_param: OUTPUT {
ctx.leave();
};
-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.DHCP_DDNS);
-} COLON LCURLY_BRACKET dhcp_ddns_params RCURLY_BRACKET {
- ctx.stack_.pop_back();
- ctx.leave();
-};
-
-dhcp_ddns_params: dhcp_ddns_param
- | dhcp_ddns_params COMMA dhcp_ddns_param
- ;
-
-dhcp_ddns_param: enable_updates
- | qualifying_suffix
- | 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 qs(new StringElement($4, ctx.loc2pos(@4)));
- ctx.stack_.back()->set("qualifying-suffix", qs);
- ctx.leave();
-};
-
-dhcp4_json_object: DHCP4 {
- ctx.enter(ctx.NO_KEYWORD);
-} COLON value {
- ctx.stack_.back()->set("Dhcp4", $4);
- ctx.leave();
-};
-
-dhcpddns_json_object: DHCPDDNS {
- ctx.enter(ctx.NO_KEYWORD);
-} COLON value {
- ctx.stack_.back()->set("DhcpDdns", $4);
- ctx.leave();
-};
-
%%
void
diff --git a/src/bin/dhcp6/parser_context.cc b/src/bin/dhcp6/parser_context.cc
index 8b6153ae76..3b9c25f86e 100644
--- a/src/bin/dhcp6/parser_context.cc
+++ b/src/bin/dhcp6/parser_context.cc
@@ -147,14 +147,16 @@ Parser6Context::context_name()
return ("client-classes");
case SERVER_ID:
return ("server-id");
- case DHCP_DDNS:
- return ("dhcp-ddns");
+ case CONTROL_SOCKET:
+ return ("control-socket");
case POOLS:
return ("pools");
case PD_POOLS:
return ("pd-pools");
case RESERVATIONS:
return ("reservations");
+ case RELAY:
+ return ("relay");
case CLIENT_CLASS:
return ("client-class");
case LOGGERS:
diff --git a/src/bin/dhcp6/parser_context.h b/src/bin/dhcp6/parser_context.h
index 3446961bd2..2ba32a572a 100644
--- a/src/bin/dhcp6/parser_context.h
+++ b/src/bin/dhcp6/parser_context.h
@@ -136,11 +136,12 @@ public:
OPTION_DATA,
CLIENT_CLASSES,
SERVER_ID,
- DHCP_DDNS,
+ CONTROL_SOCKET,
/// subnet6
POOLS,
PD_POOLS,
RESERVATIONS,
+ RELAY,
/// client-classes
CLIENT_CLASS,
/// Logging
diff --git a/src/bin/dhcp6/tests/config_parser_unittest.cc b/src/bin/dhcp6/tests/config_parser_unittest.cc
index b8423dc7ea..460fc625b4 100644
--- a/src/bin/dhcp6/tests/config_parser_unittest.cc
+++ b/src/bin/dhcp6/tests/config_parser_unittest.cc
@@ -555,7 +555,7 @@ public:
const std::string& parameter) {
ConstElementPtr x;
std::string config = createConfigWithOption(param_value, parameter);
- ConstElementPtr json = parseJSON(config);
+ ConstElementPtr json = parseDHCP6(config);
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
checkResult(x, 1);
EXPECT_TRUE(errorContainsPosition(x, "<string>"));
@@ -573,7 +573,7 @@ public:
testInvalidOptionParam(const std::map<std::string, std::string>& params) {
ConstElementPtr x;
std::string config = createConfigWithOption(params);
- ConstElementPtr json = parseJSON(config);
+ ConstElementPtr json = parseDHCP6(config);
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
checkResult(x, 1);
EXPECT_TRUE(errorContainsPosition(x, "<string>"));
@@ -674,7 +674,7 @@ public:
CfgMgr::instance().clear();
// Configure the server.
- ConstElementPtr json = parseJSON(config);
+ ConstElementPtr json = parseDHCP6(config);
// Make sure that the configuration was successful.
ConstElementPtr status;
@@ -737,11 +737,11 @@ public:
// config update.
TEST_F(Dhcp6ParserTest, version) {
- ConstElementPtr x;
-
- EXPECT_NO_THROW(x = configureDhcp6Server(srv_,
- parseJSON("{\"version\": 0}")));
+ ConstElementPtr json;
+ ASSERT_NO_THROW(json = parseDHCP6("{\"version\": 0}"));
+ ConstElementPtr x;
+ EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
// returned value must be 0 (configuration accepted)
checkResult(x, 0);
}
@@ -757,6 +757,9 @@ TEST_F(Dhcp6ParserTest, bogusCommand) {
// returned value must be 1 (configuration parse error)
checkResult(x, 1);
+
+ // it should be refused by syntax too
+ EXPECT_THROW(parseDHCP6("{\"bogus\": 5}"), Dhcp6ParseError);
}
/// The goal of this test is to verify if configuration without any
@@ -1119,7 +1122,7 @@ TEST_F(Dhcp6ParserTest, subnetLocal) {
"\"valid-lifetime\": 4000 }";
ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ASSERT_NO_THROW(json = parseDHCP6(config));
ConstElementPtr status;
EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
@@ -1216,8 +1219,7 @@ TEST_F(Dhcp6ParserTest, interfaceGlobal) {
"\"valid-lifetime\": 4000 }";
cout << config << endl;
- ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ConstElementPtr json = parseJSON(config);
ConstElementPtr status;
EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
@@ -1225,6 +1227,8 @@ TEST_F(Dhcp6ParserTest, interfaceGlobal) {
// returned value should be 1 (parse error)
checkResult(status, 1);
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
+
+ EXPECT_THROW(parseDHCP6(config), Dhcp6ParseError);
}
@@ -1248,7 +1252,7 @@ TEST_F(Dhcp6ParserTest, subnetInterfaceId) {
"\"valid-lifetime\": 4000 }";
ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ASSERT_NO_THROW(json = parseDHCP6(config));
ConstElementPtr status;
EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
@@ -1289,8 +1293,7 @@ TEST_F(Dhcp6ParserTest, interfaceIdGlobal) {
" \"subnet\": \"2001:db8:1::/64\" } ],"
"\"valid-lifetime\": 4000 }";
- ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ConstElementPtr json = parseJSON(config);
ConstElementPtr status;
EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
@@ -1298,6 +1301,8 @@ TEST_F(Dhcp6ParserTest, interfaceIdGlobal) {
// Returned value should be 1 (parse error)
checkResult(status, 1);
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
+
+ EXPECT_THROW(parseDHCP6(config), Dhcp6ParseError);
}
// This test checks if it is not possible to define a subnet with an
@@ -1315,7 +1320,7 @@ TEST_F(Dhcp6ParserTest, subnetInterfaceAndInterfaceId) {
"\"valid-lifetime\": 4000 }";
ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ASSERT_NO_THROW(json = parseDHCP6(config));
ConstElementPtr status;
EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
@@ -1517,7 +1522,7 @@ TEST_F(Dhcp6ParserTest, pdPoolBasics) {
// Convert the JSON string into Elements.
ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ASSERT_NO_THROW(json = parseDHCP6(config));
// Verify that DHCP6 configuration processing succeeds.
// Returned value must be non-empty ConstElementPtr to config result.
@@ -1655,7 +1660,7 @@ TEST_F(Dhcp6ParserTest, pdPoolList) {
// Convert the JSON string into Elements.
ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ASSERT_NO_THROW(json = parseDHCP6(config));
// Verify that DHCP6 configuration processing succeeds.
// Returned value must be non-empty ConstElementPtr to config result.
@@ -1711,7 +1716,7 @@ TEST_F(Dhcp6ParserTest, subnetAndPrefixDelegated) {
// Convert the JSON string into Elements.
ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ASSERT_NO_THROW(json = parseDHCP6(config));
// Verify that DHCP6 configuration processing succeeds.
// Returned value must be non-empty ConstElementPtr to config result.
@@ -1754,7 +1759,7 @@ TEST_F(Dhcp6ParserTest, invalidPdPools) {
const char *config[] = {
// No prefix.
- "{ \"interfaces-config\": { },"
+ "{ \"interfaces-config\": { \"interfaces\": [ ] },"
"\"preferred-lifetime\": 3000,"
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
@@ -1768,7 +1773,7 @@ TEST_F(Dhcp6ParserTest, invalidPdPools) {
"\"valid-lifetime\": 4000 }"
"] }",
// No prefix-len.
- "{ \"interfaces-config\": { },"
+ "{ \"interfaces-config\": { \"interfaces\": [ ] },"
"\"preferred-lifetime\": 3000,"
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
@@ -1781,7 +1786,7 @@ TEST_F(Dhcp6ParserTest, invalidPdPools) {
"\"valid-lifetime\": 4000 }"
"] }",
// No delegated-len.
- "{ \"interfaces-config\": { },"
+ "{ \"interfaces-config\": { \"interfaces\": [ ] },"
"\"preferred-lifetime\": 3000,"
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
@@ -1794,7 +1799,7 @@ TEST_F(Dhcp6ParserTest, invalidPdPools) {
"\"valid-lifetime\": 4000 }"
"] }",
// Delegated length is too short.
- "{ \"interfaces-config\": { },"
+ "{ \"interfaces-config\": { \"interfaces\": [ ] },"
"\"preferred-lifetime\": 3000,"
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
@@ -1813,7 +1818,7 @@ TEST_F(Dhcp6ParserTest, invalidPdPools) {
int num_msgs = sizeof(config)/sizeof(char*);
for (unsigned int i = 0; i < num_msgs; i++) {
// Convert JSON string to Elements.
- ASSERT_NO_THROW(json = parseJSON(config[i]));
+ ASSERT_NO_THROW(json = parseDHCP6(config[i]));
// Configuration processing should fail without a throw.
ASSERT_NO_THROW(x = configureDhcp6Server(srv_, json));
@@ -1903,7 +1908,7 @@ TEST_F(Dhcp6ParserTest, optionDefRecord) {
" } ]"
"}";
ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ASSERT_NO_THROW(json = parseOPTION_DEF(config));
// Make sure that the particular option definition does not exist.
OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()->
@@ -2062,7 +2067,7 @@ TEST_F(Dhcp6ParserTest, optionDefArray) {
" } ]"
"}";
ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ASSERT_NO_THROW(json = parseOPTION_DEF(config));
// Make sure that the particular option definition does not exist.
OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()->
@@ -2102,7 +2107,7 @@ TEST_F(Dhcp6ParserTest, optionDefEncapsulate) {
" } ]"
"}";
ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ASSERT_NO_THROW(json = parseOPTION_DEF(config));
// Make sure that the particular option definition does not exist.
OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()->
@@ -2192,7 +2197,7 @@ TEST_F(Dhcp6ParserTest, optionDefInvalidRecordType) {
" } ]"
"}";
ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ASSERT_NO_THROW(json = parseOPTION_DEF(config));
// Use the configuration string to create new option definition.
ConstElementPtr status;
@@ -2247,7 +2252,7 @@ TEST_F(Dhcp6ParserTest, optionDefEncapsulatedSpaceAndArray) {
" } ]"
"}";
ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ASSERT_NO_THROW(json = parseOPTION_DEF(config));
// Use the configuration string to create new option definition.
ConstElementPtr status;
@@ -2273,7 +2278,7 @@ TEST_F(Dhcp6ParserTest, optionDefEncapsulateOwnSpace) {
" } ]"
"}";
ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ASSERT_NO_THROW(json = parseOPTION_DEF(config));
// Use the configuration string to create new option definition.
ConstElementPtr status;
@@ -2696,8 +2701,7 @@ TEST_F(Dhcp6ParserTest, optionDataEncapsulate) {
" } ]"
"}";
-
- json = parseJSON(config);
+ ASSERT_NO_THROW(json = parseDHCP6(config));
EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
ASSERT_TRUE(status);
@@ -3013,7 +3017,7 @@ TEST_F(Dhcp6ParserTest, optionDataBoolean) {
sizeof(expected_option_data));
// Bogus values should not be accepted.
- params["data"] = "bugus";
+ params["data"] = "bogus";
testInvalidOptionParam(params);
params["data"] = "2";
@@ -3676,7 +3680,7 @@ TEST_F(Dhcp6ParserTest, subnetRelayInfo) {
"\"valid-lifetime\": 4000 }";
ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ASSERT_NO_THROW(json = parseDHCP6(config));
ConstElementPtr status;
EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
@@ -3816,7 +3820,7 @@ TEST_F(Dhcp6ParserTest, d2ClientConfig) {
// Convert the JSON string to configuration elements.
ConstElementPtr config;
- ASSERT_NO_THROW(config = parseJSON(config_str));
+ ASSERT_NO_THROW(config = parseDHCP6(config_str));
// Pass the configuration in for parsing.
ConstElementPtr status;
@@ -3877,7 +3881,7 @@ TEST_F(Dhcp6ParserTest, invalidD2ClientConfig) {
// Convert the JSON string to configuration elements.
ConstElementPtr config;
- ASSERT_NO_THROW(config = parseJSON(config_str));
+ ASSERT_NO_THROW(config = parseDHCP6(config_str));
// Configuration should not throw, but should fail.
ConstElementPtr status;
@@ -4203,12 +4207,13 @@ TEST_F(Dhcp6ParserTest, reservationBogus) {
"\"preferred-lifetime\": 3000,"
"\"valid-lifetime\": 4000 }";
- ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ConstElementPtr json = parseJSON(config);
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
checkResult(x, 1);
+ EXPECT_THROW(parseDHCP6(config), Dhcp6ParseError);
+
// Case 2: DUID and HW Address both specified.
config = "{ " + genIfaceConfig() + ","
"\"rebind-timer\": 2000, "
@@ -4338,6 +4343,7 @@ TEST_F(Dhcp6ParserTest, macSources) {
/// The goal of this test is to verify that MAC sources configuration can be
/// empty.
+/// Note the Dhcp6 parser requires the list to NOT be empty?!
TEST_F(Dhcp6ParserTest, macSourcesEmpty) {
ConstElementPtr status;
@@ -4414,10 +4420,11 @@ TEST_F(Dhcp6ParserTest, hostReservationPerSubnet) {
" } ],"
"\"valid-lifetime\": 4000 }";
- ConstElementPtr status;
+ ConstElementPtr json;
+ ASSERT_NO_THROW(json = parseDHCP6(HR_CONFIG));
- EXPECT_NO_THROW(status = configureDhcp6Server(srv_,
- parseJSON(HR_CONFIG)));
+ ConstElementPtr status;
+ EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
// returned value should be 0 (success)
checkResult(status, 0);
@@ -4459,7 +4466,7 @@ TEST_F(Dhcp6ParserTest, rsooNumbers) {
ConstElementPtr json;
ASSERT_NO_THROW(json =
- parseDHCP6("{ " + genIfaceConfig() + ","
+ parseDHCP6("{ " + genIfaceConfig() + ","
"\"relay-supplied-options\": [ \"10\", \"20\", \"30\" ],"
"\"preferred-lifetime\": 3000,"
"\"rebind-timer\": 2000, "
@@ -4494,7 +4501,7 @@ TEST_F(Dhcp6ParserTest, rsooNames) {
ConstElementPtr json;
ASSERT_NO_THROW(json =
- parseDHCP6("{ " + genIfaceConfig() + ","
+ parseDHCP6("{ " + genIfaceConfig() + ","
"\"relay-supplied-options\": [ \"dns-servers\", \"remote-id\" ],"
"\"preferred-lifetime\": 3000,"
"\"rebind-timer\": 2000, "
@@ -4544,7 +4551,7 @@ TEST_F(Dhcp6ParserTest, rsooNames) {
TEST_F(Dhcp6ParserTest, rsooNegativeNumber) {
ConstElementPtr json;
ASSERT_NO_THROW(json =
- parseDHCP6("{ " + genIfaceConfig() + ","
+ parseDHCP6("{ " + genIfaceConfig() + ","
"\"relay-supplied-options\": [ \"80\", \"-2\" ],"
"\"preferred-lifetime\": 3000,"
"\"rebind-timer\": 2000, "
@@ -4562,7 +4569,7 @@ TEST_F(Dhcp6ParserTest, rsooNegativeNumber) {
TEST_F(Dhcp6ParserTest, rsooBogusName) {
ConstElementPtr json;
ASSERT_NO_THROW(json =
- parseDHCP6("{ " + genIfaceConfig() + ","
+ parseDHCP6("{ " + genIfaceConfig() + ","
"\"relay-supplied-options\": [ \"bogus\", \"dns-servers\" ],"
"\"preferred-lifetime\": 3000,"
"\"rebind-timer\": 2000, "
@@ -4584,7 +4591,7 @@ TEST_F(Dhcp6ParserTest, declineTimerDefault) {
"\"subnet6\": [ ] "
"}";
ConstElementPtr config;
- ASSERT_NO_THROW(config = parseJSON(config_txt));
+ ASSERT_NO_THROW(config = parseDHCP6(config_txt));
ConstElementPtr status;
EXPECT_NO_THROW(status = configureDhcp6Server(srv_, config));
@@ -4606,7 +4613,7 @@ TEST_F(Dhcp6ParserTest, declineTimer) {
"}";
ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ASSERT_NO_THROW(json = parseDHCP6(config));
ConstElementPtr status;
EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
@@ -4627,8 +4634,7 @@ TEST_F(Dhcp6ParserTest, declineTimerError) {
"\"subnet6\": [ ]"
"}";
- ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ConstElementPtr json = parseJSON(config);
ConstElementPtr status;
EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
@@ -4638,6 +4644,9 @@ TEST_F(Dhcp6ParserTest, declineTimerError) {
// Check that the error contains error position.
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
+
+ // Check that the Dhcp6 parser catches the type error
+ EXPECT_THROW(parseDHCP6(config), Dhcp6ParseError);
}
// Check that configuration for the expired leases processing may be
@@ -4658,7 +4667,7 @@ TEST_F(Dhcp6ParserTest, expiredLeasesProcessing) {
"}";
ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ASSERT_NO_THROW(json = parseDHCP6(config));
ConstElementPtr status;
EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
@@ -4699,7 +4708,7 @@ TEST_F(Dhcp6ParserTest, expiredLeasesProcessingError) {
"}";
ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ASSERT_NO_THROW(json = parseDHCP6(config));
ConstElementPtr status;
EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
@@ -4777,13 +4786,14 @@ TEST_F(Dhcp6ParserTest, invalidClientClassDictionary) {
" } ] \n"
"} \n";
- ConstElementPtr json;
- ASSERT_NO_THROW(json = parseJSON(config));
+ ConstElementPtr json = parseJSON(config);
ConstElementPtr status;
EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
ASSERT_TRUE(status);
checkResult(status, 1);
+
+ EXPECT_THROW(parseDHCP6(config), Dhcp6ParseError);
}
// Test verifies that regular configuration does not provide any user context
diff --git a/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc
index ce007ba37d..1b4ade9daf 100644
--- a/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc
+++ b/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc
@@ -146,7 +146,7 @@ public:
ASSERT_NO_THROW(server_.reset(new NakedControlledDhcpv6Srv()));
ConstElementPtr config;
- ASSERT_NO_THROW(config = parseJSON(config_txt));
+ ASSERT_NO_THROW(config = parseDHCP6(config_txt));
ConstElementPtr answer = server_->processConfig(config);
ASSERT_TRUE(answer);
diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
index 48bc40b3a4..9e72527ce5 100644
--- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
+++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
@@ -1705,9 +1705,9 @@ TEST_F(Dhcpv6SrvTest, vendorOptionsDocsisDefinitions) {
string config_bogus = config_prefix + "99" + config_postfix;
ConstElementPtr json_bogus;
- ASSERT_NO_THROW(json_bogus = parseJSON(config_bogus));
+ ASSERT_NO_THROW(json_bogus = parseDHCP6(config_bogus));
ConstElementPtr json_valid;
- ASSERT_NO_THROW(json_valid = parseJSON(config_valid));
+ ASSERT_NO_THROW(json_valid = parseDHCP6(config_valid));
NakedDhcpv6Srv srv(0);
diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.h b/src/bin/dhcp6/tests/dhcp6_test_utils.h
index d15de0879f..47b4a92500 100644
--- a/src/bin/dhcp6/tests/dhcp6_test_utils.h
+++ b/src/bin/dhcp6/tests/dhcp6_test_utils.h
@@ -656,7 +656,9 @@ parseDHCP6(const std::string& in)
return (ctx.parseString(in, isc::dhcp::Parser6Context::SUBPARSER_DHCP6));
}
catch (const std::exception& ex) {
+#ifdef ENABLE_DEBUG
std::cout << "EXCEPTION: " << ex.what() << std::endl;
+#endif // ENABLE_DEBUG
throw;
}
}
@@ -670,7 +672,9 @@ parseOPTION_DEF(const std::string& in)
return (ctx.parseString(in, isc::dhcp::Parser6Context::SUBPARSER_OPTION_DEF));
}
catch (const std::exception& ex) {
+#ifdef ENABLE_DEBUG
std::cout << "EXCEPTION: " << ex.what() << std::endl;
+#endif // ENABLE_DEBUG
throw;
}
}