Commit 361561aa authored by Francis Dupont's avatar Francis Dupont
Browse files

[master] Finishing merge of trac5097 (migrate pool config)

parents d02bd8b4 dad9ff71
......@@ -24,7 +24,11 @@
# Define a single subnet.
"subnet6": [
{
"pools": [ { "pool": "2001:db8:1::/80" } ],
"pools": [
{
"pool": "2001:db8:1::/80",
"user-context": { "charging": true }
} ],
"subnet": "2001:db8:1::/64",
"interface": "ethX"
}
......
......@@ -39,6 +39,8 @@
# addresses from the other pool, or the clients obtaining
# stateless configuration will be assigned subnet specific value
# of option 12, i.e. 2001:db8:1:0:ff00::1.
# For DHCPv6 subnets can have prefix delegation pools too so
# a pd-pools with an option-data is defined too.
"subnet6": [
{
"option-data": [
......@@ -65,6 +67,19 @@
"pool": "2001:db8:1::500 - 2001:db8:2::1000"
}
],
"pd-pools": [
{
"prefix": "2001:2b8:2::",
"prefix-len": 56,
"delegated-len": 64,
"option-data": [
{
"code": 12,
"data": "3001:cafe::12:"
}
]
}
],
"subnet": "2001:db8:1::/64",
"interface": "ethX"
}
......
This diff is collapsed.
......@@ -473,6 +473,15 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
}
}
\"user-context\" {
switch(driver.ctx_) {
case isc::dhcp::Parser4Context::POOLS:
return isc::dhcp::Dhcp4Parser::make_USER_CONTEXT(driver.loc_);
default:
return isc::dhcp::Dhcp4Parser::make_STRING("user-context", driver.loc_);
}
}
\"subnet\" {
switch(driver.ctx_) {
case isc::dhcp::Parser4Context::SUBNET4:
......
This diff is collapsed.
......@@ -306,7 +306,6 @@ namespace isc { namespace dhcp {
{
// value
// socket_type
// db_type
// ncr_protocol_value
// replace_client_name_value
char dummy1[sizeof(ElementPtr)];
......@@ -366,65 +365,65 @@ namespace isc { namespace dhcp {
TOKEN_LEASE_DATABASE = 276,
TOKEN_HOSTS_DATABASE = 277,
TOKEN_TYPE = 278,
TOKEN_MEMFILE = 279,
TOKEN_MYSQL = 280,
TOKEN_POSTGRESQL = 281,
TOKEN_CQL = 282,
TOKEN_USER = 283,
TOKEN_PASSWORD = 284,
TOKEN_HOST = 285,
TOKEN_PERSIST = 286,
TOKEN_LFC_INTERVAL = 287,
TOKEN_READONLY = 288,
TOKEN_CONNECT_TIMEOUT = 289,
TOKEN_VALID_LIFETIME = 290,
TOKEN_RENEW_TIMER = 291,
TOKEN_REBIND_TIMER = 292,
TOKEN_DECLINE_PROBATION_PERIOD = 293,
TOKEN_SUBNET4 = 294,
TOKEN_SUBNET_4O6_INTERFACE = 295,
TOKEN_SUBNET_4O6_INTERFACE_ID = 296,
TOKEN_SUBNET_4O6_SUBNET = 297,
TOKEN_OPTION_DEF = 298,
TOKEN_OPTION_DATA = 299,
TOKEN_NAME = 300,
TOKEN_DATA = 301,
TOKEN_CODE = 302,
TOKEN_SPACE = 303,
TOKEN_CSV_FORMAT = 304,
TOKEN_RECORD_TYPES = 305,
TOKEN_ENCAPSULATE = 306,
TOKEN_ARRAY = 307,
TOKEN_POOLS = 308,
TOKEN_POOL = 309,
TOKEN_SUBNET = 310,
TOKEN_INTERFACE = 311,
TOKEN_INTERFACE_ID = 312,
TOKEN_ID = 313,
TOKEN_RAPID_COMMIT = 314,
TOKEN_RESERVATION_MODE = 315,
TOKEN_HOST_RESERVATION_IDENTIFIERS = 316,
TOKEN_CLIENT_CLASSES = 317,
TOKEN_TEST = 318,
TOKEN_CLIENT_CLASS = 319,
TOKEN_RESERVATIONS = 320,
TOKEN_DUID = 321,
TOKEN_HW_ADDRESS = 322,
TOKEN_CIRCUIT_ID = 323,
TOKEN_CLIENT_ID = 324,
TOKEN_HOSTNAME = 325,
TOKEN_RELAY = 326,
TOKEN_IP_ADDRESS = 327,
TOKEN_HOOKS_LIBRARIES = 328,
TOKEN_LIBRARY = 329,
TOKEN_PARAMETERS = 330,
TOKEN_EXPIRED_LEASES_PROCESSING = 331,
TOKEN_RECLAIM_TIMER_WAIT_TIME = 332,
TOKEN_FLUSH_RECLAIMED_TIMER_WAIT_TIME = 333,
TOKEN_HOLD_RECLAIMED_TIME = 334,
TOKEN_MAX_RECLAIM_LEASES = 335,
TOKEN_MAX_RECLAIM_TIME = 336,
TOKEN_UNWARNED_RECLAIM_CYCLES = 337,
TOKEN_USER = 279,
TOKEN_PASSWORD = 280,
TOKEN_HOST = 281,
TOKEN_PERSIST = 282,
TOKEN_LFC_INTERVAL = 283,
TOKEN_READONLY = 284,
TOKEN_VALID_LIFETIME = 285,
TOKEN_RENEW_TIMER = 286,
TOKEN_REBIND_TIMER = 287,
TOKEN_DECLINE_PROBATION_PERIOD = 288,
TOKEN_SUBNET4 = 289,
TOKEN_SUBNET_4O6_INTERFACE = 290,
TOKEN_SUBNET_4O6_INTERFACE_ID = 291,
TOKEN_SUBNET_4O6_SUBNET = 292,
TOKEN_OPTION_DEF = 293,
TOKEN_OPTION_DATA = 294,
TOKEN_NAME = 295,
TOKEN_DATA = 296,
TOKEN_CODE = 297,
TOKEN_SPACE = 298,
TOKEN_CSV_FORMAT = 299,
TOKEN_RECORD_TYPES = 300,
TOKEN_ENCAPSULATE = 301,
TOKEN_ARRAY = 302,
TOKEN_POOLS = 303,
TOKEN_POOL = 304,
TOKEN_SUBNET = 305,
TOKEN_INTERFACE = 306,
TOKEN_INTERFACE_ID = 307,
TOKEN_ID = 308,
TOKEN_RAPID_COMMIT = 309,
TOKEN_RESERVATION_MODE = 310,
TOKEN_HOST_RESERVATION_IDENTIFIERS = 311,
TOKEN_CLIENT_CLASSES = 312,
TOKEN_TEST = 313,
TOKEN_CLIENT_CLASS = 314,
TOKEN_RESERVATIONS = 315,
TOKEN_DUID = 316,
TOKEN_HW_ADDRESS = 317,
TOKEN_CIRCUIT_ID = 318,
TOKEN_CLIENT_ID = 319,
TOKEN_HOSTNAME = 320,
TOKEN_RELAY = 321,
TOKEN_IP_ADDRESS = 322,
TOKEN_HOOKS_LIBRARIES = 323,
TOKEN_LIBRARY = 324,
TOKEN_PARAMETERS = 325,
TOKEN_EXPIRED_LEASES_PROCESSING = 326,
TOKEN_RECLAIM_TIMER_WAIT_TIME = 327,
TOKEN_FLUSH_RECLAIMED_TIMER_WAIT_TIME = 328,
TOKEN_HOLD_RECLAIMED_TIME = 329,
TOKEN_MAX_RECLAIM_LEASES = 330,
TOKEN_MAX_RECLAIM_TIME = 331,
TOKEN_UNWARNED_RECLAIM_CYCLES = 332,
TOKEN_SERVER_ID = 333,
TOKEN_IDENTIFIER = 334,
TOKEN_HTYPE = 335,
TOKEN_TIME = 336,
TOKEN_ENTERPRISE_ID = 337,
TOKEN_DHCP4O6_PORT = 338,
TOKEN_CONTROL_SOCKET = 339,
TOKEN_SOCKET_TYPE = 340,
......@@ -676,22 +675,6 @@ namespace isc { namespace dhcp {
symbol_type
make_TYPE (const location_type& l);
static inline
symbol_type
make_MEMFILE (const location_type& l);
static inline
symbol_type
make_MYSQL (const location_type& l);
static inline
symbol_type
make_POSTGRESQL (const location_type& l);
static inline
symbol_type
make_CQL (const location_type& l);
static inline
symbol_type
make_USER (const location_type& l);
......@@ -716,10 +699,6 @@ namespace isc { namespace dhcp {
symbol_type
make_READONLY (const location_type& l);
static inline
symbol_type
make_CONNECT_TIMEOUT (const location_type& l);
static inline
symbol_type
make_VALID_LIFETIME (const location_type& l);
......@@ -912,6 +891,26 @@ namespace isc { namespace dhcp {
symbol_type
make_UNWARNED_RECLAIM_CYCLES (const location_type& l);
static inline
symbol_type
make_SERVER_ID (const location_type& l);
static inline
symbol_type
make_IDENTIFIER (const location_type& l);
static inline
symbol_type
make_HTYPE (const location_type& l);
static inline
symbol_type
make_TIME (const location_type& l);
static inline
symbol_type
make_ENTERPRISE_ID (const location_type& l);
static inline
symbol_type
make_DHCP4O6_PORT (const location_type& l);
......@@ -1313,8 +1312,8 @@ namespace isc { namespace dhcp {
enum
{
yyeof_ = 0,
yylast_ = 713, ///< Last index in yytable_.
yynnts_ = 299, ///< Number of nonterminal symbols.
yylast_ = 732, ///< Last index in yytable_.
yynnts_ = 305, ///< Number of nonterminal symbols.
yyfinal_ = 24, ///< Termination state number.
yyterror_ = 1,
yyerrcode_ = 256,
......@@ -1410,9 +1409,8 @@ namespace isc { namespace dhcp {
{
case 145: // value
case 186: // socket_type
case 195: // db_type
case 393: // ncr_protocol_value
case 402: // replace_client_name_value
case 399: // ncr_protocol_value
case 408: // replace_client_name_value
value.copy< ElementPtr > (other.value);
break;
......@@ -1451,9 +1449,8 @@ namespace isc { namespace dhcp {
{
case 145: // value
case 186: // socket_type
case 195: // db_type
case 393: // ncr_protocol_value
case 402: // replace_client_name_value
case 399: // ncr_protocol_value
case 408: // replace_client_name_value
value.copy< ElementPtr > (v);
break;
......@@ -1551,9 +1548,8 @@ namespace isc { namespace dhcp {
{
case 145: // value
case 186: // socket_type
case 195: // db_type
case 393: // ncr_protocol_value
case 402: // replace_client_name_value
case 399: // ncr_protocol_value
case 408: // replace_client_name_value
value.template destroy< ElementPtr > ();
break;
......@@ -1598,9 +1594,8 @@ namespace isc { namespace dhcp {
{
case 145: // value
case 186: // socket_type
case 195: // db_type
case 393: // ncr_protocol_value
case 402: // replace_client_name_value
case 399: // ncr_protocol_value
case 408: // replace_client_name_value
value.move< ElementPtr > (s.value);
break;
......@@ -1825,30 +1820,6 @@ namespace isc { namespace dhcp {
return symbol_type (token::TOKEN_TYPE, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_MEMFILE (const location_type& l)
{
return symbol_type (token::TOKEN_MEMFILE, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_MYSQL (const location_type& l)
{
return symbol_type (token::TOKEN_MYSQL, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_POSTGRESQL (const location_type& l)
{
return symbol_type (token::TOKEN_POSTGRESQL, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_CQL (const location_type& l)
{
return symbol_type (token::TOKEN_CQL, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_USER (const location_type& l)
{
......@@ -1885,12 +1856,6 @@ namespace isc { namespace dhcp {
return symbol_type (token::TOKEN_READONLY, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_CONNECT_TIMEOUT (const location_type& l)
{
return symbol_type (token::TOKEN_CONNECT_TIMEOUT, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_VALID_LIFETIME (const location_type& l)
{
......@@ -2179,6 +2144,36 @@ namespace isc { namespace dhcp {
return symbol_type (token::TOKEN_UNWARNED_RECLAIM_CYCLES, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_SERVER_ID (const location_type& l)
{
return symbol_type (token::TOKEN_SERVER_ID, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_IDENTIFIER (const location_type& l)
{
return symbol_type (token::TOKEN_IDENTIFIER, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_HTYPE (const location_type& l)
{
return symbol_type (token::TOKEN_HTYPE, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_TIME (const location_type& l)
{
return symbol_type (token::TOKEN_TIME, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_ENTERPRISE_ID (const location_type& l)
{
return symbol_type (token::TOKEN_ENTERPRISE_ID, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_DHCP4O6_PORT (const location_type& l)
{
......@@ -2476,7 +2471,7 @@ namespace isc { namespace dhcp {
#line 14 "dhcp4_parser.yy" // lalr1.cc:377
} } // isc::dhcp
#line 2480 "dhcp4_parser.h" // lalr1.cc:377
#line 2475 "dhcp4_parser.h" // lalr1.cc:377
......
......@@ -98,6 +98,7 @@ using namespace std;
POOLS "pools"
POOL "pool"
USER_CONTEXT "user-context"
SUBNET "subnet"
INTERFACE "interface"
......@@ -194,6 +195,7 @@ using namespace std;
%token <bool> BOOLEAN "boolean"
%type <ElementPtr> value
%type <ElementPtr> map_value
%type <ElementPtr> socket_type
%type <ElementPtr> db_type
%type <ElementPtr> ncr_protocol_value
......@@ -251,6 +253,8 @@ map2: LCURLY_BRACKET {
// for it.
};
map_value: map2 { $$ = ctx.stack_.back(); ctx.stack_.pop_back(); };
// Assignments rule
map_content: %empty // empty map
| not_empty_map
......@@ -1141,6 +1145,7 @@ pool_params: pool_param
pool_param: pool_entry
| option_data_list
| user_context
| unknown_map_entry
;
......@@ -1152,6 +1157,13 @@ pool_entry: POOL {
ctx.leave();
};
user_context: USER_CONTEXT {
ctx.enter(ctx.NO_KEYWORD);
} COLON map_value {
ctx.stack_.back()->set("user-context", $4);
ctx.leave();
};
// --- end of pools definition -------------------------------
// --- reservations ------------------------------------------
......
......@@ -54,18 +54,6 @@ namespace {
///
/// It is useful for parsing Dhcp4/subnet4[X]/pool parameters.
class Pool4Parser : public PoolParser {
public:
/// @brief Constructor.
///
/// @param param_name name of the parameter. Note, it is passed through
/// but unused, parameter is currently always "Dhcp4/subnet4[X]/pool"
/// @param pools storage container in which to store the parsed pool
/// upon "commit"
Pool4Parser(const std::string& param_name, PoolStoragePtr pools)
:PoolParser(param_name, pools, AF_INET) {
}
protected:
/// @brief Creates a Pool4 object given a IPv4 prefix and the prefix length.
///
......@@ -90,15 +78,23 @@ protected:
}
};
class Pools4ListParser : public PoolsListParser {
/// @brief Specialization of the pool list parser for DHCPv4
class Pools4ListParser : PoolsListParser {
public:
Pools4ListParser(const std::string& dummy, PoolStoragePtr pools)
:PoolsListParser(dummy, pools) {
}
protected:
virtual ParserPtr poolParserMaker(PoolStoragePtr storage) {
return (ParserPtr(new Pool4Parser("pool", storage)));
/// @brief parses the actual structure
///
/// This method parses the actual list of pools.
///
/// @param pools storage container in which to store the parsed pool.
/// @param pools_list a list of pool structures
/// @throw isc::dhcp::DhcpConfigError when pool parsing fails
void parse(PoolStoragePtr pools,
isc::data::ConstElementPtr pools_list) {
BOOST_FOREACH(ConstElementPtr pool, pools_list->listValue()) {
Pool4Parser parser;
parser.parse(pools, pool, AF_INET);
}
}
};
......@@ -123,6 +119,13 @@ public:
///
/// @param subnet A new subnet being configured.
void build(ConstElementPtr subnet) {
/// Parse Pools first.
ConstElementPtr pools = subnet->get("pools");
if (pools) {
Pools4ListParser parser;
parser.parse(pools_, pools);
}
SubnetConfigParser::build(subnet);
if (subnet_) {
......@@ -186,9 +189,8 @@ protected:
(config_id.compare("next-server") == 0) ||
(config_id.compare("reservation-mode") == 0)) {
parser = new StringParser(config_id, string_values_);
} else if (config_id.compare("pools") == 0) {
parser = new Pools4ListParser(config_id, pools_);
// relay has been converted to SimpleParser already.
// pools has been converted to SimpleParser already.
// relay has been converted to SimpleParser already.
// option-data has been converted to SimpleParser already.
} else if (config_id.compare("match-client-id") == 0) {
parser = new BooleanParser(config_id, boolean_values_);
......
// Generated 201701251401
// Generated 201701120056
// A Bison parser, made by GNU Bison 3.0.4.
// Locations for Bison parsers in C++
......
// Generated 201701251401
// Generated 201701120056
// A Bison parser, made by GNU Bison 3.0.4.
// Positions for Bison parsers in C++
......
// Generated 201701251401
// Generated 201701120056
// A Bison parser, made by GNU Bison 3.0.4.
// Stack handling for Bison parsers in C++
......
// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012-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
......@@ -107,6 +107,28 @@ const char* PARSER_CONFIGS[] = {
" ],"
" \"subnet\": \"192.0.2.0/24\""
" } ]"
"}",
// Configuration 3: one min-max pool with user context containing lw4over6 parameters
"{"
" \"interfaces-config\": {"
" \"interfaces\": [\"*\" ]"
" },"
" \"valid-lifetime\": 4000,"
" \"rebind-timer\": 2000,"
" \"renew-timer\": 1000,"
" \"subnet4\": [ {"
" \"pools\": [ "
" { \"pool\": \"192.0.2.0 - 192.0.2.15\","
" \"user-context\": {"
" \"integer-param\": 42,"
" \"string-param\": \"Sagittarius\","
" \"bool-param\": true"
" }"
" }"
" ],"
" \"subnet\": \"192.0.2.0/24\""
" } ]"
"}"
};
......@@ -572,8 +594,9 @@ public:
void getPool(const std::string& config, size_t subnet_index,
size_t pool_index, PoolPtr& pool) {
ConstElementPtr status;
ElementPtr json = Element::fromJSON(config);
ConstElementPtr json;
EXPECT_NO_THROW(json = parseDHCP4(config, true));
EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(status);
checkResult(status, 0);
......@@ -1443,6 +1466,132 @@ TEST_F(Dhcp4ParserTest, poolPrefixLen) {
EXPECT_EQ(4000, subnet->getValid());
}
// Goal of this test is to verify if invalid pool definitions
// return a location in the error message.
TEST_F(Dhcp4ParserTest, badPools) {
// not a prefix
string config_bogus1 = "{ " + genIfaceConfig() + "," +
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
"\"subnet4\": [ { "
" \"pools\": [ { \"pool\": \"foo/28\" } ],"
" \"subnet\": \"192.0.2.0/24\" } ],"
"\"valid-lifetime\": 4000 }";
// not a length
string config_bogus2 = "{ " + genIfaceConfig() + "," +
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
"\"subnet4\": [ { "
" \"pools\": [ { \"pool\": \"192.0.2.128/foo\" } ],"
" \"subnet\": \"192.0.2.0/24\" } ],"
"\"valid-lifetime\": 4000 }";
// invalid prefix length
string config_bogus3 = "{ " + genIfaceConfig() + "," +
"\"rebind-timer\": 2000, "