mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 13:37:55 +00:00
[master] kea-dhpc4/6 now support relay ip-addresses
Merges in branch 'trac5535'
This commit is contained in:
commit
f4601abdb6
@ -3995,20 +3995,20 @@ for each subnet. Here's an example:
|
||||
{
|
||||
"name": "kakapo",
|
||||
<userinput>"relay": {
|
||||
"ip-address": "192.3.5.6"
|
||||
"ip-addresses": [ "192.3.5.6" ]
|
||||
}</userinput>,
|
||||
"subnet4": [
|
||||
{
|
||||
"subnet": "192.0.2.0/26",
|
||||
<userinput>"relay": {
|
||||
"ip-address": "192.1.1.1"
|
||||
"ip-addresses": [ "192.1.1.1" ]
|
||||
}</userinput>,
|
||||
"pools": [ { "pool": "192.0.2.63 - 192.0.2.63" } ]
|
||||
},
|
||||
{
|
||||
"subnet": "10.0.0.0/24",
|
||||
<userinput>"relay": {
|
||||
"ip-address": "192.2.2.2"
|
||||
"ip-addresses": [ "192.2.2.2" ]
|
||||
}</userinput>,
|
||||
"pools": [ { "pool": "10.0.0.16 - 10.0.0.16" } ]
|
||||
}
|
||||
@ -4138,7 +4138,6 @@ desired outcome if one desires to service only clients of known properties
|
||||
"interface" or "relay" parameter. All subnets belonging to this shared
|
||||
network will inherit those parameters.
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
@ -4311,7 +4310,7 @@ autogenerated IDs are not stable across configuration changes.</para>
|
||||
"subnet": "192.0.2.0/24",
|
||||
"pools": [ { "pool": "192.0.2.10 - 192.0.2.20" } ],
|
||||
<userinput>"relay": {
|
||||
"ip-address": "10.0.0.1"
|
||||
"ip-addresses": [ "10.0.0.1" ]
|
||||
}</userinput>,
|
||||
...
|
||||
}
|
||||
@ -4321,8 +4320,17 @@ autogenerated IDs are not stable across configuration changes.</para>
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>If "relay" is specified, the "ip-address" parameter within
|
||||
<para>If "relay" is specified, the "ip-addresses" parameter within
|
||||
it is mandatory.</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
As of Kea 1.4, the "ip-address" parameter has been deprecated in favor
|
||||
of "ip-addresses" which supports specifying a list of addresses.
|
||||
Configuration parsing, will honor the singular form for now but users are
|
||||
encouraged to migrate.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
</section>
|
||||
|
||||
@ -4351,14 +4359,14 @@ autogenerated IDs are not stable across configuration changes.</para>
|
||||
"pools": [ { "pool": "10.1.1.2 - 10.1.1.20" } ],
|
||||
<userinput>"client-class" "docsis3.0",
|
||||
"relay": {
|
||||
"ip-address": "10.1.1.1"
|
||||
"ip-addresses": [ "10.1.1.1 ]"
|
||||
}</userinput>
|
||||
},
|
||||
{
|
||||
"subnet": "192.0.2.0/24",
|
||||
"pools": [ { "pool": "192.0.2.10 - 192.0.2.20" } ],
|
||||
<userinput>"relay": {
|
||||
"ip-address": "10.1.1.1"
|
||||
"ip-addresses": [ "10.1.1.1" ]
|
||||
}</userinput>
|
||||
}
|
||||
],
|
||||
|
@ -3496,7 +3496,7 @@ If not specified, the default value is:
|
||||
// Subnets from this shared network will be selected for clients
|
||||
// communicating via relay agent having the specified IP address.
|
||||
"relay": {
|
||||
"ip-address": "2001:db8:2:34::1"
|
||||
"ip-addresses": [ "2001:db8:2:34::1" ]
|
||||
},
|
||||
|
||||
// This starts a list of subnets in this shared network.
|
||||
@ -3523,7 +3523,7 @@ If not specified, the default value is:
|
||||
"subnet": "2001:db9::/48",
|
||||
"pools": [ { "pool": "2001:db9::/64" } ],
|
||||
"relay": {
|
||||
"ip-address": "2001:db8:1:2::1"
|
||||
"ip-addresses": [ "2001:db8:1:2::1" ]
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -3555,7 +3555,7 @@ If not specified, the default value is:
|
||||
{
|
||||
"name": "lab-network3",
|
||||
"relay": {
|
||||
"ip-address": "2001:db8:2:34::1"
|
||||
"ip-addresses": [ "2001:db8:2:34::1" ]
|
||||
},
|
||||
|
||||
// This applies to all subnets in this shared network, unless
|
||||
@ -3671,13 +3671,13 @@ for each subnet. Here's an example:
|
||||
{
|
||||
"name": "kakapo",
|
||||
<userinput>"relay": {
|
||||
"ip-address": "2001:db8::abcd"
|
||||
"ip-addresses": [ "2001:db8::abcd" ]
|
||||
}</userinput>,
|
||||
"subnet6": [
|
||||
{
|
||||
"subnet": "2001:db8::/64",
|
||||
<userinput>"relay": {
|
||||
"ip-address": "2001:db8::1234"
|
||||
"ip-addresses": [ "2001:db8::1234" ]
|
||||
}</userinput>,
|
||||
"pools": [ { "pool": "2001:db8::1 - 2001:db8::ffff" } ]
|
||||
},
|
||||
@ -3685,7 +3685,7 @@ for each subnet. Here's an example:
|
||||
"subnet": "3ffe:abcd::/64",
|
||||
"pools": [ { "pool": "3ffe:abcd::1 - 3ffe:abcd::ffff" } ],
|
||||
<userinput>"relay": {
|
||||
"ip-address": "3ffe:abcd::cafe"
|
||||
"ip-addresses": [ "3ffe:abcd::cafe" ]
|
||||
}</userinput>
|
||||
}
|
||||
]
|
||||
@ -3730,7 +3730,7 @@ as long as it is valid IPv6 address.</para>
|
||||
{
|
||||
"name": "galah",
|
||||
"relay": {
|
||||
"ip-address": "2001:db8:2:34::1"
|
||||
"ip-address": [ "2001:db8:2:34::1" ]
|
||||
},
|
||||
"subnet6": [
|
||||
{
|
||||
@ -3781,7 +3781,7 @@ as long as it is valid IPv6 address.</para>
|
||||
{
|
||||
"name": "galah",
|
||||
"relay": {
|
||||
"ip-address": "2001:db8:2:34::1"
|
||||
"ip-addresses": [ "2001:db8:2:34::1" ]
|
||||
},
|
||||
"subnet6": [
|
||||
{
|
||||
@ -3833,7 +3833,7 @@ desired outcome if one desires to service only clients of known properties
|
||||
{
|
||||
"name": "frog",
|
||||
"relay": {
|
||||
"ip-address": "2001:db8:2:34::1"
|
||||
"ip-addresses": [ "2001:db8:2:34::1" ]
|
||||
},
|
||||
"subnet6": [
|
||||
{
|
||||
@ -4252,7 +4252,7 @@ autogenerated IDs are not stable across configuration changes.
|
||||
}
|
||||
],
|
||||
<userinput>"relay": {
|
||||
"ip-address": "3000::1"
|
||||
"ip-addresses": [ "3000::1" ]
|
||||
}</userinput>
|
||||
}
|
||||
]
|
||||
@ -4260,9 +4260,18 @@ autogenerated IDs are not stable across configuration changes.
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>If "relay" is specified, the "ip-address" parameter within
|
||||
<para>If "relay" is specified, the "ip-addresses" parameter within
|
||||
it is mandatory.</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
As of Kea 1.4, the "ip-address" parameter in "relay" has been deprecated
|
||||
in favor of "ip-addresses" which supports specifying a list of addresses.
|
||||
Configuration parsing, will honor the singular form for now but users are
|
||||
encouraged to migrate.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
</section>
|
||||
|
||||
<section xml:id="dhcp6-client-class-relay">
|
||||
@ -4293,7 +4302,7 @@ autogenerated IDs are not stable across configuration changes.
|
||||
],
|
||||
<userinput>"client-class": "VENDOR_CLASS_docsis3.0",
|
||||
"relay": {
|
||||
"ip-address": "3000::1"
|
||||
"ip-addresses": [ "3000::1" ]
|
||||
}</userinput>
|
||||
},
|
||||
|
||||
@ -4305,7 +4314,7 @@ autogenerated IDs are not stable across configuration changes.
|
||||
}
|
||||
],
|
||||
<userinput>"relay": {
|
||||
"ip-address": "3000::1"
|
||||
"ip-addresses": [ "3000::1" ]
|
||||
}</userinput>
|
||||
}
|
||||
]
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1052,6 +1052,15 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
|
||||
}
|
||||
}
|
||||
|
||||
\"ip-addresses\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::RELAY:
|
||||
return isc::dhcp::Dhcp4Parser::make_IP_ADDRESSES(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp4Parser::make_STRING("ip-addresses", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"hooks-libraries\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::DHCP4:
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -441,70 +441,71 @@ namespace isc { namespace dhcp {
|
||||
TOKEN_FLEX_ID = 348,
|
||||
TOKEN_RELAY = 349,
|
||||
TOKEN_IP_ADDRESS = 350,
|
||||
TOKEN_HOOKS_LIBRARIES = 351,
|
||||
TOKEN_LIBRARY = 352,
|
||||
TOKEN_PARAMETERS = 353,
|
||||
TOKEN_EXPIRED_LEASES_PROCESSING = 354,
|
||||
TOKEN_RECLAIM_TIMER_WAIT_TIME = 355,
|
||||
TOKEN_FLUSH_RECLAIMED_TIMER_WAIT_TIME = 356,
|
||||
TOKEN_HOLD_RECLAIMED_TIME = 357,
|
||||
TOKEN_MAX_RECLAIM_LEASES = 358,
|
||||
TOKEN_MAX_RECLAIM_TIME = 359,
|
||||
TOKEN_UNWARNED_RECLAIM_CYCLES = 360,
|
||||
TOKEN_DHCP4O6_PORT = 361,
|
||||
TOKEN_CONTROL_SOCKET = 362,
|
||||
TOKEN_SOCKET_TYPE = 363,
|
||||
TOKEN_SOCKET_NAME = 364,
|
||||
TOKEN_DHCP_DDNS = 365,
|
||||
TOKEN_ENABLE_UPDATES = 366,
|
||||
TOKEN_QUALIFYING_SUFFIX = 367,
|
||||
TOKEN_SERVER_IP = 368,
|
||||
TOKEN_SERVER_PORT = 369,
|
||||
TOKEN_SENDER_IP = 370,
|
||||
TOKEN_SENDER_PORT = 371,
|
||||
TOKEN_MAX_QUEUE_SIZE = 372,
|
||||
TOKEN_NCR_PROTOCOL = 373,
|
||||
TOKEN_NCR_FORMAT = 374,
|
||||
TOKEN_ALWAYS_INCLUDE_FQDN = 375,
|
||||
TOKEN_OVERRIDE_NO_UPDATE = 376,
|
||||
TOKEN_OVERRIDE_CLIENT_UPDATE = 377,
|
||||
TOKEN_REPLACE_CLIENT_NAME = 378,
|
||||
TOKEN_GENERATED_PREFIX = 379,
|
||||
TOKEN_TCP = 380,
|
||||
TOKEN_JSON = 381,
|
||||
TOKEN_WHEN_PRESENT = 382,
|
||||
TOKEN_NEVER = 383,
|
||||
TOKEN_ALWAYS = 384,
|
||||
TOKEN_WHEN_NOT_PRESENT = 385,
|
||||
TOKEN_LOGGING = 386,
|
||||
TOKEN_LOGGERS = 387,
|
||||
TOKEN_OUTPUT_OPTIONS = 388,
|
||||
TOKEN_OUTPUT = 389,
|
||||
TOKEN_DEBUGLEVEL = 390,
|
||||
TOKEN_SEVERITY = 391,
|
||||
TOKEN_FLUSH = 392,
|
||||
TOKEN_MAXSIZE = 393,
|
||||
TOKEN_MAXVER = 394,
|
||||
TOKEN_DHCP6 = 395,
|
||||
TOKEN_DHCPDDNS = 396,
|
||||
TOKEN_CONTROL_AGENT = 397,
|
||||
TOKEN_TOPLEVEL_JSON = 398,
|
||||
TOKEN_TOPLEVEL_DHCP4 = 399,
|
||||
TOKEN_SUB_DHCP4 = 400,
|
||||
TOKEN_SUB_INTERFACES4 = 401,
|
||||
TOKEN_SUB_SUBNET4 = 402,
|
||||
TOKEN_SUB_POOL4 = 403,
|
||||
TOKEN_SUB_RESERVATION = 404,
|
||||
TOKEN_SUB_OPTION_DEFS = 405,
|
||||
TOKEN_SUB_OPTION_DEF = 406,
|
||||
TOKEN_SUB_OPTION_DATA = 407,
|
||||
TOKEN_SUB_HOOKS_LIBRARY = 408,
|
||||
TOKEN_SUB_DHCP_DDNS = 409,
|
||||
TOKEN_SUB_LOGGING = 410,
|
||||
TOKEN_STRING = 411,
|
||||
TOKEN_INTEGER = 412,
|
||||
TOKEN_FLOAT = 413,
|
||||
TOKEN_BOOLEAN = 414
|
||||
TOKEN_IP_ADDRESSES = 351,
|
||||
TOKEN_HOOKS_LIBRARIES = 352,
|
||||
TOKEN_LIBRARY = 353,
|
||||
TOKEN_PARAMETERS = 354,
|
||||
TOKEN_EXPIRED_LEASES_PROCESSING = 355,
|
||||
TOKEN_RECLAIM_TIMER_WAIT_TIME = 356,
|
||||
TOKEN_FLUSH_RECLAIMED_TIMER_WAIT_TIME = 357,
|
||||
TOKEN_HOLD_RECLAIMED_TIME = 358,
|
||||
TOKEN_MAX_RECLAIM_LEASES = 359,
|
||||
TOKEN_MAX_RECLAIM_TIME = 360,
|
||||
TOKEN_UNWARNED_RECLAIM_CYCLES = 361,
|
||||
TOKEN_DHCP4O6_PORT = 362,
|
||||
TOKEN_CONTROL_SOCKET = 363,
|
||||
TOKEN_SOCKET_TYPE = 364,
|
||||
TOKEN_SOCKET_NAME = 365,
|
||||
TOKEN_DHCP_DDNS = 366,
|
||||
TOKEN_ENABLE_UPDATES = 367,
|
||||
TOKEN_QUALIFYING_SUFFIX = 368,
|
||||
TOKEN_SERVER_IP = 369,
|
||||
TOKEN_SERVER_PORT = 370,
|
||||
TOKEN_SENDER_IP = 371,
|
||||
TOKEN_SENDER_PORT = 372,
|
||||
TOKEN_MAX_QUEUE_SIZE = 373,
|
||||
TOKEN_NCR_PROTOCOL = 374,
|
||||
TOKEN_NCR_FORMAT = 375,
|
||||
TOKEN_ALWAYS_INCLUDE_FQDN = 376,
|
||||
TOKEN_OVERRIDE_NO_UPDATE = 377,
|
||||
TOKEN_OVERRIDE_CLIENT_UPDATE = 378,
|
||||
TOKEN_REPLACE_CLIENT_NAME = 379,
|
||||
TOKEN_GENERATED_PREFIX = 380,
|
||||
TOKEN_TCP = 381,
|
||||
TOKEN_JSON = 382,
|
||||
TOKEN_WHEN_PRESENT = 383,
|
||||
TOKEN_NEVER = 384,
|
||||
TOKEN_ALWAYS = 385,
|
||||
TOKEN_WHEN_NOT_PRESENT = 386,
|
||||
TOKEN_LOGGING = 387,
|
||||
TOKEN_LOGGERS = 388,
|
||||
TOKEN_OUTPUT_OPTIONS = 389,
|
||||
TOKEN_OUTPUT = 390,
|
||||
TOKEN_DEBUGLEVEL = 391,
|
||||
TOKEN_SEVERITY = 392,
|
||||
TOKEN_FLUSH = 393,
|
||||
TOKEN_MAXSIZE = 394,
|
||||
TOKEN_MAXVER = 395,
|
||||
TOKEN_DHCP6 = 396,
|
||||
TOKEN_DHCPDDNS = 397,
|
||||
TOKEN_CONTROL_AGENT = 398,
|
||||
TOKEN_TOPLEVEL_JSON = 399,
|
||||
TOKEN_TOPLEVEL_DHCP4 = 400,
|
||||
TOKEN_SUB_DHCP4 = 401,
|
||||
TOKEN_SUB_INTERFACES4 = 402,
|
||||
TOKEN_SUB_SUBNET4 = 403,
|
||||
TOKEN_SUB_POOL4 = 404,
|
||||
TOKEN_SUB_RESERVATION = 405,
|
||||
TOKEN_SUB_OPTION_DEFS = 406,
|
||||
TOKEN_SUB_OPTION_DEF = 407,
|
||||
TOKEN_SUB_OPTION_DATA = 408,
|
||||
TOKEN_SUB_HOOKS_LIBRARY = 409,
|
||||
TOKEN_SUB_DHCP_DDNS = 410,
|
||||
TOKEN_SUB_LOGGING = 411,
|
||||
TOKEN_STRING = 412,
|
||||
TOKEN_INTEGER = 413,
|
||||
TOKEN_FLOAT = 414,
|
||||
TOKEN_BOOLEAN = 415
|
||||
};
|
||||
};
|
||||
|
||||
@ -995,6 +996,10 @@ namespace isc { namespace dhcp {
|
||||
symbol_type
|
||||
make_IP_ADDRESS (const location_type& l);
|
||||
|
||||
static inline
|
||||
symbol_type
|
||||
make_IP_ADDRESSES (const location_type& l);
|
||||
|
||||
static inline
|
||||
symbol_type
|
||||
make_HOOKS_LIBRARIES (const location_type& l);
|
||||
@ -1456,12 +1461,12 @@ namespace isc { namespace dhcp {
|
||||
enum
|
||||
{
|
||||
yyeof_ = 0,
|
||||
yylast_ = 933, ///< Last index in yytable_.
|
||||
yynnts_ = 352, ///< Number of nonterminal symbols.
|
||||
yylast_ = 935, ///< Last index in yytable_.
|
||||
yynnts_ = 353, ///< Number of nonterminal symbols.
|
||||
yyfinal_ = 28, ///< Termination state number.
|
||||
yyterror_ = 1,
|
||||
yyerrcode_ = 256,
|
||||
yyntokens_ = 160 ///< Number of tokens.
|
||||
yyntokens_ = 161 ///< Number of tokens.
|
||||
};
|
||||
|
||||
|
||||
@ -1519,9 +1524,9 @@ namespace isc { namespace dhcp {
|
||||
125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
|
||||
135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
|
||||
145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
|
||||
155, 156, 157, 158, 159
|
||||
155, 156, 157, 158, 159, 160
|
||||
};
|
||||
const unsigned int user_token_number_max_ = 414;
|
||||
const unsigned int user_token_number_max_ = 415;
|
||||
const token_number_type undef_token_ = 2;
|
||||
|
||||
if (static_cast<int>(t) <= yyeof_)
|
||||
@ -1554,30 +1559,30 @@ namespace isc { namespace dhcp {
|
||||
{
|
||||
switch (other.type_get ())
|
||||
{
|
||||
case 175: // value
|
||||
case 179: // map_value
|
||||
case 217: // socket_type
|
||||
case 220: // outbound_interface_value
|
||||
case 236: // db_type
|
||||
case 320: // hr_mode
|
||||
case 467: // ncr_protocol_value
|
||||
case 475: // replace_client_name_value
|
||||
case 176: // value
|
||||
case 180: // map_value
|
||||
case 218: // socket_type
|
||||
case 221: // outbound_interface_value
|
||||
case 237: // db_type
|
||||
case 321: // hr_mode
|
||||
case 469: // ncr_protocol_value
|
||||
case 477: // replace_client_name_value
|
||||
value.copy< ElementPtr > (other.value);
|
||||
break;
|
||||
|
||||
case 159: // "boolean"
|
||||
case 160: // "boolean"
|
||||
value.copy< bool > (other.value);
|
||||
break;
|
||||
|
||||
case 158: // "floating point"
|
||||
case 159: // "floating point"
|
||||
value.copy< double > (other.value);
|
||||
break;
|
||||
|
||||
case 157: // "integer"
|
||||
case 158: // "integer"
|
||||
value.copy< int64_t > (other.value);
|
||||
break;
|
||||
|
||||
case 156: // "constant string"
|
||||
case 157: // "constant string"
|
||||
value.copy< std::string > (other.value);
|
||||
break;
|
||||
|
||||
@ -1598,30 +1603,30 @@ namespace isc { namespace dhcp {
|
||||
(void) v;
|
||||
switch (this->type_get ())
|
||||
{
|
||||
case 175: // value
|
||||
case 179: // map_value
|
||||
case 217: // socket_type
|
||||
case 220: // outbound_interface_value
|
||||
case 236: // db_type
|
||||
case 320: // hr_mode
|
||||
case 467: // ncr_protocol_value
|
||||
case 475: // replace_client_name_value
|
||||
case 176: // value
|
||||
case 180: // map_value
|
||||
case 218: // socket_type
|
||||
case 221: // outbound_interface_value
|
||||
case 237: // db_type
|
||||
case 321: // hr_mode
|
||||
case 469: // ncr_protocol_value
|
||||
case 477: // replace_client_name_value
|
||||
value.copy< ElementPtr > (v);
|
||||
break;
|
||||
|
||||
case 159: // "boolean"
|
||||
case 160: // "boolean"
|
||||
value.copy< bool > (v);
|
||||
break;
|
||||
|
||||
case 158: // "floating point"
|
||||
case 159: // "floating point"
|
||||
value.copy< double > (v);
|
||||
break;
|
||||
|
||||
case 157: // "integer"
|
||||
case 158: // "integer"
|
||||
value.copy< int64_t > (v);
|
||||
break;
|
||||
|
||||
case 156: // "constant string"
|
||||
case 157: // "constant string"
|
||||
value.copy< std::string > (v);
|
||||
break;
|
||||
|
||||
@ -1701,30 +1706,30 @@ namespace isc { namespace dhcp {
|
||||
// Type destructor.
|
||||
switch (yytype)
|
||||
{
|
||||
case 175: // value
|
||||
case 179: // map_value
|
||||
case 217: // socket_type
|
||||
case 220: // outbound_interface_value
|
||||
case 236: // db_type
|
||||
case 320: // hr_mode
|
||||
case 467: // ncr_protocol_value
|
||||
case 475: // replace_client_name_value
|
||||
case 176: // value
|
||||
case 180: // map_value
|
||||
case 218: // socket_type
|
||||
case 221: // outbound_interface_value
|
||||
case 237: // db_type
|
||||
case 321: // hr_mode
|
||||
case 469: // ncr_protocol_value
|
||||
case 477: // replace_client_name_value
|
||||
value.template destroy< ElementPtr > ();
|
||||
break;
|
||||
|
||||
case 159: // "boolean"
|
||||
case 160: // "boolean"
|
||||
value.template destroy< bool > ();
|
||||
break;
|
||||
|
||||
case 158: // "floating point"
|
||||
case 159: // "floating point"
|
||||
value.template destroy< double > ();
|
||||
break;
|
||||
|
||||
case 157: // "integer"
|
||||
case 158: // "integer"
|
||||
value.template destroy< int64_t > ();
|
||||
break;
|
||||
|
||||
case 156: // "constant string"
|
||||
case 157: // "constant string"
|
||||
value.template destroy< std::string > ();
|
||||
break;
|
||||
|
||||
@ -1751,30 +1756,30 @@ namespace isc { namespace dhcp {
|
||||
super_type::move(s);
|
||||
switch (this->type_get ())
|
||||
{
|
||||
case 175: // value
|
||||
case 179: // map_value
|
||||
case 217: // socket_type
|
||||
case 220: // outbound_interface_value
|
||||
case 236: // db_type
|
||||
case 320: // hr_mode
|
||||
case 467: // ncr_protocol_value
|
||||
case 475: // replace_client_name_value
|
||||
case 176: // value
|
||||
case 180: // map_value
|
||||
case 218: // socket_type
|
||||
case 221: // outbound_interface_value
|
||||
case 237: // db_type
|
||||
case 321: // hr_mode
|
||||
case 469: // ncr_protocol_value
|
||||
case 477: // replace_client_name_value
|
||||
value.move< ElementPtr > (s.value);
|
||||
break;
|
||||
|
||||
case 159: // "boolean"
|
||||
case 160: // "boolean"
|
||||
value.move< bool > (s.value);
|
||||
break;
|
||||
|
||||
case 158: // "floating point"
|
||||
case 159: // "floating point"
|
||||
value.move< double > (s.value);
|
||||
break;
|
||||
|
||||
case 157: // "integer"
|
||||
case 158: // "integer"
|
||||
value.move< int64_t > (s.value);
|
||||
break;
|
||||
|
||||
case 156: // "constant string"
|
||||
case 157: // "constant string"
|
||||
value.move< std::string > (s.value);
|
||||
break;
|
||||
|
||||
@ -1848,7 +1853,8 @@ namespace isc { namespace dhcp {
|
||||
375, 376, 377, 378, 379, 380, 381, 382, 383, 384,
|
||||
385, 386, 387, 388, 389, 390, 391, 392, 393, 394,
|
||||
395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
|
||||
405, 406, 407, 408, 409, 410, 411, 412, 413, 414
|
||||
405, 406, 407, 408, 409, 410, 411, 412, 413, 414,
|
||||
415
|
||||
};
|
||||
return static_cast<token_type> (yytoken_number_[type]);
|
||||
}
|
||||
@ -2417,6 +2423,12 @@ namespace isc { namespace dhcp {
|
||||
return symbol_type (token::TOKEN_IP_ADDRESS, l);
|
||||
}
|
||||
|
||||
Dhcp4Parser::symbol_type
|
||||
Dhcp4Parser::make_IP_ADDRESSES (const location_type& l)
|
||||
{
|
||||
return symbol_type (token::TOKEN_IP_ADDRESSES, l);
|
||||
}
|
||||
|
||||
Dhcp4Parser::symbol_type
|
||||
Dhcp4Parser::make_HOOKS_LIBRARIES (const location_type& l)
|
||||
{
|
||||
@ -2804,7 +2816,7 @@ namespace isc { namespace dhcp {
|
||||
|
||||
#line 14 "dhcp4_parser.yy" // lalr1.cc:377
|
||||
} } // isc::dhcp
|
||||
#line 2808 "dhcp4_parser.h" // lalr1.cc:377
|
||||
#line 2820 "dhcp4_parser.h" // lalr1.cc:377
|
||||
|
||||
|
||||
|
||||
|
@ -145,6 +145,7 @@ using namespace std;
|
||||
|
||||
RELAY "relay"
|
||||
IP_ADDRESS "ip-address"
|
||||
IP_ADDRESSES "ip-addresses"
|
||||
|
||||
HOOKS_LIBRARIES "hooks-libraries"
|
||||
LIBRARY "library"
|
||||
@ -1586,6 +1587,16 @@ ip_address: IP_ADDRESS {
|
||||
ctx.leave();
|
||||
};
|
||||
|
||||
ip_addresses: IP_ADDRESSES {
|
||||
ElementPtr l(new ListElement(ctx.loc2pos(@1)));
|
||||
ctx.stack_.back()->set("ip-addresses", l);
|
||||
ctx.stack_.push_back(l);
|
||||
ctx.enter(ctx.NO_KEYWORD);
|
||||
} COLON list_strings {
|
||||
ctx.stack_.pop_back();
|
||||
ctx.leave();
|
||||
};
|
||||
|
||||
duid: DUID {
|
||||
ctx.enter(ctx.NO_KEYWORD);
|
||||
} COLON STRING {
|
||||
@ -1657,13 +1668,9 @@ relay: RELAY {
|
||||
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();
|
||||
};
|
||||
relay_map: ip_address
|
||||
| ip_addresses
|
||||
;
|
||||
|
||||
// --- end of relay definitions ------------------------------
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
// Generated 201804111443
|
||||
// A Bison parser, made by GNU Bison 3.0.4.
|
||||
|
||||
// Locations for Bison parsers in C++
|
||||
|
@ -1,4 +1,3 @@
|
||||
// Generated 201804111443
|
||||
// A Bison parser, made by GNU Bison 3.0.4.
|
||||
|
||||
// Positions for Bison parsers in C++
|
||||
|
@ -1,4 +1,3 @@
|
||||
// Generated 201804111443
|
||||
// A Bison parser, made by GNU Bison 3.0.4.
|
||||
|
||||
// Stack handling for Bison parsers in C++
|
||||
|
@ -260,7 +260,7 @@ public:
|
||||
void checkResult(ConstElementPtr status, int expected_code) {
|
||||
ASSERT_TRUE(status);
|
||||
comment_ = parseAnswer(rcode_, status);
|
||||
EXPECT_EQ(expected_code, rcode_);
|
||||
EXPECT_EQ(expected_code, rcode_) << "error text:" << comment_->stringValue();
|
||||
}
|
||||
|
||||
/// @brief Convenience method for running configuration
|
||||
@ -1377,7 +1377,7 @@ TEST_F(Dhcp4ParserTest, nextServerOverride) {
|
||||
"\"renew-timer\": 1000, "
|
||||
"\"next-server\": \"192.0.0.1\", "
|
||||
"\"server-hostname\": \"nohost\","
|
||||
"\"boot-file-name\": \"nofile\","
|
||||
"\"boot-file-name\": \"nofile\","
|
||||
"\"subnet4\": [ { "
|
||||
" \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
|
||||
" \"next-server\": \"1.2.3.4\", "
|
||||
@ -4089,9 +4089,53 @@ TEST_F(Dhcp4ParserTest, subnetRelayInfo) {
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ("192.0.2.123", subnet->getRelayInfo().addr_.toText());
|
||||
|
||||
EXPECT_TRUE(subnet->hasRelays());
|
||||
EXPECT_TRUE(subnet->hasRelayAddress(IOAddress("192.0.2.123")));
|
||||
}
|
||||
|
||||
// This test checks if it is possible to specify a list of relays
|
||||
TEST_F(Dhcp4ParserTest, subnetRelayInfoList) {
|
||||
|
||||
ConstElementPtr status;
|
||||
|
||||
// A config with relay information.
|
||||
string config = "{ " + genIfaceConfig() + "," +
|
||||
"\"rebind-timer\": 2000, "
|
||||
"\"renew-timer\": 1000, "
|
||||
"\"subnet4\": [ { "
|
||||
" \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
|
||||
" \"renew-timer\": 1, "
|
||||
" \"rebind-timer\": 2, "
|
||||
" \"valid-lifetime\": 4,"
|
||||
" \"relay\": { "
|
||||
" \"ip-addresses\": [ \"192.0.3.123\", \"192.0.3.124\" ]"
|
||||
" },"
|
||||
" \"subnet\": \"192.0.2.0/24\" } ],"
|
||||
"\"valid-lifetime\": 4000 }";
|
||||
|
||||
ConstElementPtr json;
|
||||
ASSERT_NO_THROW(json = parseDHCP4(config));
|
||||
extractConfig(config);
|
||||
|
||||
EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json));
|
||||
|
||||
// returned value should be 0 (configuration success)
|
||||
checkResult(status, 0);
|
||||
|
||||
SubnetSelector selector;
|
||||
selector.giaddr_ = IOAddress("192.0.2.200");
|
||||
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->selectSubnet(selector);
|
||||
ASSERT_TRUE(subnet);
|
||||
|
||||
EXPECT_TRUE(subnet->hasRelays());
|
||||
EXPECT_TRUE(subnet->hasRelayAddress(IOAddress("192.0.3.123")));
|
||||
EXPECT_TRUE(subnet->hasRelayAddress(IOAddress("192.0.3.124")));
|
||||
}
|
||||
|
||||
|
||||
// Goal of this test is to verify that multiple subnets can be configured
|
||||
// with defined client classes.
|
||||
TEST_F(Dhcp4ParserTest, classifySubnets) {
|
||||
@ -5652,7 +5696,7 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) {
|
||||
EXPECT_EQ(IOAddress("1.2.3.4"), s->getSiaddr());
|
||||
EXPECT_EQ("foo", s->getSname());
|
||||
EXPECT_EQ("bar", s->getFilename());
|
||||
EXPECT_EQ(IOAddress("5.6.7.8"), s->getRelayInfo().addr_);
|
||||
EXPECT_TRUE(s->hasRelayAddress(IOAddress("5.6.7.8")));
|
||||
EXPECT_EQ(Network::HR_OUT_OF_POOL, s->getHostReservationMode());
|
||||
|
||||
// For the second subnet, the renew-timer should be 100, because it
|
||||
@ -5667,7 +5711,7 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) {
|
||||
EXPECT_EQ(IOAddress("11.22.33.44"), s->getSiaddr());
|
||||
EXPECT_EQ("some-name.example.org", s->getSname());
|
||||
EXPECT_EQ("bootfile.efi", s->getFilename());
|
||||
EXPECT_EQ(IOAddress("55.66.77.88"), s->getRelayInfo().addr_);
|
||||
EXPECT_TRUE(s->hasRelayAddress(IOAddress("55.66.77.88")));
|
||||
EXPECT_EQ(Network::HR_DISABLED, s->getHostReservationMode());
|
||||
|
||||
// Ok, now check the second shared subnet.
|
||||
@ -5686,7 +5730,7 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) {
|
||||
EXPECT_EQ(IOAddress("0.0.0.0"), s->getSiaddr());
|
||||
EXPECT_TRUE(s->getSname().empty());
|
||||
EXPECT_TRUE(s->getFilename().empty());
|
||||
EXPECT_EQ(IOAddress("0.0.0.0"), s->getRelayInfo().addr_);
|
||||
EXPECT_FALSE(s->hasRelays());
|
||||
EXPECT_EQ(Network::HR_ALL, s->getHostReservationMode());
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1196,6 +1196,7 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
|
||||
\"ip-addresses\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::RESERVATIONS:
|
||||
case isc::dhcp::Parser6Context::RELAY:
|
||||
return isc::dhcp::Dhcp6Parser::make_IP_ADDRESSES(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp6Parser::make_STRING("ip-addresses", driver.loc_);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1480,8 +1480,8 @@ namespace isc { namespace dhcp {
|
||||
enum
|
||||
{
|
||||
yyeof_ = 0,
|
||||
yylast_ = 979, ///< Last index in yytable_.
|
||||
yynnts_ = 366, ///< Number of nonterminal symbols.
|
||||
yylast_ = 981, ///< Last index in yytable_.
|
||||
yynnts_ = 367, ///< Number of nonterminal symbols.
|
||||
yyfinal_ = 30, ///< Termination state number.
|
||||
yyterror_ = 1,
|
||||
yyerrcode_ = 256,
|
||||
@ -1582,9 +1582,9 @@ namespace isc { namespace dhcp {
|
||||
case 185: // map_value
|
||||
case 235: // db_type
|
||||
case 318: // hr_mode
|
||||
case 453: // duid_type
|
||||
case 486: // ncr_protocol_value
|
||||
case 494: // replace_client_name_value
|
||||
case 454: // duid_type
|
||||
case 487: // ncr_protocol_value
|
||||
case 495: // replace_client_name_value
|
||||
value.copy< ElementPtr > (other.value);
|
||||
break;
|
||||
|
||||
@ -1625,9 +1625,9 @@ namespace isc { namespace dhcp {
|
||||
case 185: // map_value
|
||||
case 235: // db_type
|
||||
case 318: // hr_mode
|
||||
case 453: // duid_type
|
||||
case 486: // ncr_protocol_value
|
||||
case 494: // replace_client_name_value
|
||||
case 454: // duid_type
|
||||
case 487: // ncr_protocol_value
|
||||
case 495: // replace_client_name_value
|
||||
value.copy< ElementPtr > (v);
|
||||
break;
|
||||
|
||||
@ -1727,9 +1727,9 @@ namespace isc { namespace dhcp {
|
||||
case 185: // map_value
|
||||
case 235: // db_type
|
||||
case 318: // hr_mode
|
||||
case 453: // duid_type
|
||||
case 486: // ncr_protocol_value
|
||||
case 494: // replace_client_name_value
|
||||
case 454: // duid_type
|
||||
case 487: // ncr_protocol_value
|
||||
case 495: // replace_client_name_value
|
||||
value.template destroy< ElementPtr > ();
|
||||
break;
|
||||
|
||||
@ -1776,9 +1776,9 @@ namespace isc { namespace dhcp {
|
||||
case 185: // map_value
|
||||
case 235: // db_type
|
||||
case 318: // hr_mode
|
||||
case 453: // duid_type
|
||||
case 486: // ncr_protocol_value
|
||||
case 494: // replace_client_name_value
|
||||
case 454: // duid_type
|
||||
case 487: // ncr_protocol_value
|
||||
case 495: // replace_client_name_value
|
||||
value.move< ElementPtr > (s.value);
|
||||
break;
|
||||
|
||||
|
@ -1684,11 +1684,15 @@ relay: RELAY {
|
||||
ctx.leave();
|
||||
};
|
||||
|
||||
relay_map: IP_ADDRESS {
|
||||
relay_map: ip_address
|
||||
| ip_addresses
|
||||
;
|
||||
|
||||
ip_address: IP_ADDRESS {
|
||||
ctx.enter(ctx.NO_KEYWORD);
|
||||
} COLON STRING {
|
||||
ElementPtr ip(new StringElement($4, ctx.loc2pos(@4)));
|
||||
ctx.stack_.back()->set("ip-address", ip);
|
||||
ElementPtr addr(new StringElement($4, ctx.loc2pos(@4)));
|
||||
ctx.stack_.back()->set("ip-address", addr);
|
||||
ctx.leave();
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
// Generated 201804111534
|
||||
// A Bison parser, made by GNU Bison 3.0.4.
|
||||
|
||||
// Locations for Bison parsers in C++
|
||||
|
@ -1,4 +1,3 @@
|
||||
// Generated 201804111534
|
||||
// A Bison parser, made by GNU Bison 3.0.4.
|
||||
|
||||
// Positions for Bison parsers in C++
|
||||
|
@ -1,4 +1,3 @@
|
||||
// Generated 201804111534
|
||||
// A Bison parser, made by GNU Bison 3.0.4.
|
||||
|
||||
// Stack handling for Bison parsers in C++
|
||||
|
@ -4142,7 +4142,43 @@ TEST_F(Dhcp6ParserTest, subnetRelayInfo) {
|
||||
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
|
||||
selectSubnet(IOAddress("2001:db8:1::1"), classify_);
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ("2001:db8:1::abcd", subnet->getRelayInfo().addr_.toText());
|
||||
|
||||
EXPECT_TRUE(subnet->hasRelays());
|
||||
EXPECT_TRUE(subnet->hasRelayAddress(IOAddress("2001:db8:1::abcd")));
|
||||
}
|
||||
|
||||
// This test checks if it is possible to specify a list of relays
|
||||
TEST_F(Dhcp6ParserTest, subnetRelayInfoList) {
|
||||
// A config with relay information.
|
||||
string config = "{ " + genIfaceConfig() + ","
|
||||
"\"rebind-timer\": 2000, "
|
||||
"\"renew-timer\": 1000, "
|
||||
"\"subnet6\": [ { "
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:1::1 - 2001:db8:1::ffff\" } ],"
|
||||
" \"relay\": { "
|
||||
" \"ip-addresses\": [ \"2001:db9::abcd\", \"2001:db9::abce\" ]"
|
||||
" },"
|
||||
" \"subnet\": \"2001:db8:1::/64\" } ],"
|
||||
"\"preferred-lifetime\": 3000, "
|
||||
"\"valid-lifetime\": 4000 }";
|
||||
|
||||
ConstElementPtr json;
|
||||
ASSERT_NO_THROW(json = parseDHCP6(config));
|
||||
extractConfig(config);
|
||||
|
||||
ConstElementPtr status;
|
||||
EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
|
||||
|
||||
// returned value should be 0 (configuration success)
|
||||
checkResult(status, 0);
|
||||
|
||||
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
|
||||
selectSubnet(IOAddress("2001:db9::abcd"), classify_, true);
|
||||
ASSERT_TRUE(subnet);
|
||||
|
||||
EXPECT_TRUE(subnet->hasRelays());
|
||||
EXPECT_TRUE(subnet->hasRelayAddress(IOAddress("2001:db9::abcd")));
|
||||
EXPECT_TRUE(subnet->hasRelayAddress(IOAddress("2001:db9::abce")));
|
||||
}
|
||||
|
||||
// Goal of this test is to verify that multiple subnets can be configured
|
||||
@ -6008,7 +6044,7 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDerive) {
|
||||
ASSERT_TRUE(s);
|
||||
ASSERT_TRUE(s->getInterfaceId());
|
||||
EXPECT_TRUE(iface_id1.equals(s->getInterfaceId()));
|
||||
EXPECT_EQ(IOAddress("1111::1"), s->getRelayInfo().addr_);
|
||||
EXPECT_TRUE(s->hasRelayAddress(IOAddress("1111::1")));
|
||||
EXPECT_TRUE(s->getRapidCommit());
|
||||
EXPECT_EQ(Network::HR_DISABLED, s->getHostReservationMode());
|
||||
|
||||
@ -6019,7 +6055,7 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDerive) {
|
||||
s = checkSubnet(*subs, "2001:db2::/48", 100, 200, 300, 400);
|
||||
ASSERT_TRUE(s->getInterfaceId());
|
||||
EXPECT_TRUE(iface_id2.equals(s->getInterfaceId()));
|
||||
EXPECT_EQ(IOAddress("2222::2"), s->getRelayInfo().addr_);
|
||||
EXPECT_TRUE(s->hasRelayAddress(IOAddress("2222::2")));
|
||||
EXPECT_TRUE(s->getRapidCommit());
|
||||
EXPECT_EQ(Network::HR_OUT_OF_POOL, s->getHostReservationMode());
|
||||
|
||||
@ -6034,7 +6070,7 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDerive) {
|
||||
// This subnet should derive its renew-timer from global scope.
|
||||
s = checkSubnet(*subs, "2001:db3::/48", 1, 2, 3, 4);
|
||||
EXPECT_FALSE(s->getInterfaceId());
|
||||
EXPECT_EQ(IOAddress("::"), s->getRelayInfo().addr_);
|
||||
EXPECT_FALSE(s->hasRelays());
|
||||
EXPECT_FALSE(s->getRapidCommit());
|
||||
EXPECT_EQ(Network::HR_ALL, s->getHostReservationMode());
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -137,17 +137,16 @@ CfgSubnets4::selectSubnet(const SubnetSelector& selector) const {
|
||||
|
||||
// If relay information is specified for this subnet, it must match.
|
||||
// Otherwise, we ignore this subnet.
|
||||
if (!(*subnet)->getRelayInfo().addr_.isV4Zero()) {
|
||||
if (selector.giaddr_ != (*subnet)->getRelayInfo().addr_) {
|
||||
if ((*subnet)->hasRelays()) {
|
||||
if (!(*subnet)->hasRelayAddress(selector.giaddr_)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Relay information is not specified on the subnet level,
|
||||
// so let's try matching on the shared network level.
|
||||
SharedNetwork4Ptr network;
|
||||
(*subnet)->getSharedNetwork(network);
|
||||
if (!network || (selector.giaddr_ != network->getRelayInfo().addr_)) {
|
||||
if (!network || !(network->hasRelayAddress(selector.giaddr_))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -116,16 +116,17 @@ CfgSubnets6::selectSubnet(const asiolink::IOAddress& address,
|
||||
for (Subnet6Collection::const_iterator subnet = subnets_.begin();
|
||||
subnet != subnets_.end(); ++subnet) {
|
||||
|
||||
// If the specified address matches the relay address, return this
|
||||
// If the specified address matches a relay address, return this
|
||||
// subnet.
|
||||
if (is_relay_address &&
|
||||
((*subnet)->getRelayInfo().addr_ == address) &&
|
||||
((*subnet)->hasRelayAddress(address)) &&
|
||||
(*subnet)->clientSupported(client_classes)) {
|
||||
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE,
|
||||
DHCPSRV_CFGMGR_SUBNET6_RELAY)
|
||||
.arg((*subnet)->toText()).arg(address.toText());
|
||||
return (*subnet);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,6 +84,12 @@ This warning message is issued on an attempt to configure multiple options with
|
||||
same option code for the particular subnet. Adding multiple options is uncommon
|
||||
for DHCPv6, but it is not prohibited.
|
||||
|
||||
% DHCPSRV_CFGMGR_RELAY_IP_ADDRESS_DEPRECATED "relay" uses "ip-address", which has been deprecated, please use "ip-addresses": %1
|
||||
This is debug message issued when the "relay" element being parse
|
||||
contains "ip-address" rather than its replacement, "ip-addresses".
|
||||
The server will still honor the value but users are encouraged to
|
||||
move to the new list parameter.
|
||||
|
||||
% DHCPSRV_CFGMGR_SOCKET_RAW_UNSUPPORTED use of raw sockets is unsupported on this OS, UDP sockets will be used
|
||||
This warning message is logged when the user specified that the
|
||||
DHCPv4 server should use the raw sockets to receive the DHCP
|
||||
|
@ -16,8 +16,56 @@ using namespace isc::data;
|
||||
namespace isc {
|
||||
namespace dhcp {
|
||||
|
||||
Network::RelayInfo::RelayInfo(const isc::asiolink::IOAddress& addr)
|
||||
:addr_(addr) {
|
||||
void
|
||||
Network::RelayInfo::addAddress(const asiolink::IOAddress& addr) {
|
||||
if (containsAddress(addr)) {
|
||||
isc_throw (BadValue, "RelayInfo already contains address: "
|
||||
<< addr.toText());
|
||||
}
|
||||
|
||||
addresses_.push_back(addr);
|
||||
}
|
||||
|
||||
bool
|
||||
Network::RelayInfo::hasAddresses() const {
|
||||
return (!addresses_.empty());
|
||||
}
|
||||
|
||||
bool
|
||||
Network::RelayInfo::containsAddress(const asiolink::IOAddress& addr) const {
|
||||
for (auto address = addresses_.begin(); address != addresses_.end();
|
||||
++address) {
|
||||
if ((*address) == addr) {
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
const IOAddressList&
|
||||
Network::RelayInfo::getAddresses() const {
|
||||
return (addresses_);
|
||||
}
|
||||
|
||||
void
|
||||
Network::addRelayAddress(const asiolink::IOAddress& addr) {
|
||||
relay_.addAddress(addr);
|
||||
}
|
||||
|
||||
bool
|
||||
Network::hasRelays() const {
|
||||
return (relay_.hasAddresses());
|
||||
}
|
||||
|
||||
bool
|
||||
Network::hasRelayAddress(const asiolink::IOAddress& addr) const {
|
||||
return (relay_.containsAddress(addr));
|
||||
}
|
||||
|
||||
const IOAddressList&
|
||||
Network::getRelayAddresses() const {
|
||||
return (relay_.getAddresses());
|
||||
}
|
||||
|
||||
bool
|
||||
@ -61,11 +109,15 @@ Network::toElement() const {
|
||||
map->set("interface", Element::create(iface));
|
||||
}
|
||||
|
||||
// Set relay info
|
||||
const RelayInfo& relay_info = getRelayInfo();
|
||||
ElementPtr relay = Element::createMap();
|
||||
relay->set("ip-address", Element::create(relay_info.addr_.toText()));
|
||||
map->set("relay", relay);
|
||||
ElementPtr relay_map = Element::createMap();
|
||||
ElementPtr address_list = Element::createList();
|
||||
const IOAddressList addresses = getRelayAddresses();
|
||||
for (auto address = addresses.begin(); address != addresses.end(); ++address) {
|
||||
address_list->add(Element::create((*address).toText()));
|
||||
}
|
||||
|
||||
relay_map->set("ip-addresses", address_list);
|
||||
map->set("relay", relay_map);
|
||||
|
||||
// Set client-class
|
||||
const ClientClass& cclass = getClientClass();
|
||||
|
@ -24,6 +24,9 @@
|
||||
namespace isc {
|
||||
namespace dhcp {
|
||||
|
||||
/// List of IOAddresses
|
||||
typedef std::vector<isc::asiolink::IOAddress> IOAddressList;
|
||||
|
||||
/// @brief Common interface representing a network to which the DHCP clients
|
||||
/// are connected.
|
||||
///
|
||||
@ -44,24 +47,42 @@ namespace dhcp {
|
||||
/// derived classes.
|
||||
class Network : public virtual UserContext, public data::CfgToElement {
|
||||
public:
|
||||
|
||||
/// @brief Holds optional information about relay.
|
||||
///
|
||||
/// In some cases it is beneficial to have additional information about
|
||||
/// a relay configured in the subnet. For now, the structure holds only
|
||||
/// IP address, but there may potentially be additional parameters added
|
||||
/// IP addresses, but there may potentially be additional parameters added
|
||||
/// later, e.g. relay interface-id or relay-id.
|
||||
struct RelayInfo {
|
||||
class RelayInfo {
|
||||
public:
|
||||
|
||||
/// @brief default and the only constructor
|
||||
/// @brief Adds an address to the list of addresses
|
||||
///
|
||||
/// @param addr an IP address of the relay (may be :: or 0.0.0.0)
|
||||
RelayInfo(const isc::asiolink::IOAddress& addr);
|
||||
/// @param addr address to add
|
||||
/// @throw BadValue if the address is already in the list
|
||||
void addAddress(const asiolink::IOAddress& addr);
|
||||
|
||||
/// @brief IP address of the relay
|
||||
isc::asiolink::IOAddress addr_;
|
||||
/// @brief Returns const reference to the list of addresses
|
||||
///
|
||||
/// @return const reference to the list of addresses
|
||||
const IOAddressList& getAddresses() const;
|
||||
|
||||
/// @brief Indicates whether or not the address list has entries
|
||||
///
|
||||
/// @return True if the address list is not empty
|
||||
bool hasAddresses() const;
|
||||
|
||||
/// @brief Checks the address list for the given address
|
||||
///
|
||||
/// @return True if the address is found in the address list
|
||||
bool containsAddress(const asiolink::IOAddress& addr) const;
|
||||
|
||||
private:
|
||||
/// @brief List of relay IP addresses
|
||||
IOAddressList addresses_;
|
||||
};
|
||||
|
||||
|
||||
/// @brief Specifies allowed host reservation mode.
|
||||
///
|
||||
typedef enum {
|
||||
@ -88,8 +109,7 @@ public:
|
||||
|
||||
/// @brief Constructor.
|
||||
Network()
|
||||
: iface_name_(), relay_(asiolink::IOAddress::IPV4_ZERO_ADDRESS()),
|
||||
client_class_(""), t1_(0), t2_(0), valid_(0),
|
||||
: iface_name_(), client_class_(""), t1_(0), t2_(0), valid_(0),
|
||||
host_reservation_mode_(HR_ALL), cfg_option_(new CfgOption()) {
|
||||
}
|
||||
|
||||
@ -151,6 +171,28 @@ public:
|
||||
return (relay_);
|
||||
}
|
||||
|
||||
/// @brief Adds an address to the list addresses in the network's relay info
|
||||
///
|
||||
/// @param addr address of the relay
|
||||
/// @throw BadValue if the address is already in the list
|
||||
void addRelayAddress(const asiolink::IOAddress& addr);
|
||||
|
||||
/// @brief Returns the list of relay addresses from the network's relay info
|
||||
///
|
||||
/// @return const reference to the list of addresses
|
||||
const IOAddressList& getRelayAddresses() const;
|
||||
|
||||
/// @brief Indicates if network's relay info has relay addresses
|
||||
///
|
||||
/// @return True the relay list is not empty, false otherwise
|
||||
bool hasRelays() const;
|
||||
|
||||
/// @brief Tests if the network's relay info contains the given address
|
||||
///
|
||||
/// @param address address to search for in the relay list
|
||||
/// @return True if a relay with the given address is found, false otherwise
|
||||
bool hasRelayAddress(const asiolink::IOAddress& address) const;
|
||||
|
||||
/// @brief Checks whether this network supports client that belongs to
|
||||
/// specified classes.
|
||||
///
|
||||
@ -363,7 +405,6 @@ public:
|
||||
/// @brief Constructor.
|
||||
Network6()
|
||||
: Network(), preferred_(0), interface_id_(), rapid_commit_(false) {
|
||||
setRelayInfo(asiolink::IOAddress::IPV6_ZERO_ADDRESS());
|
||||
}
|
||||
|
||||
/// @brief Returns preferred lifetime (in seconds)
|
||||
|
@ -233,23 +233,81 @@ RelayInfoParser::RelayInfoParser(const Option::Universe& family)
|
||||
};
|
||||
|
||||
void
|
||||
RelayInfoParser::parse(const isc::dhcp::Network::RelayInfoPtr& cfg,
|
||||
ConstElementPtr relay_info) {
|
||||
// There is only one parameter which is mandatory
|
||||
IOAddress ip = getAddress(relay_info, "ip-address");
|
||||
RelayInfoParser::parse(const isc::dhcp::Network::RelayInfoPtr& relay_info,
|
||||
ConstElementPtr relay_elem) {
|
||||
|
||||
// Check if the address family matches.
|
||||
if ((ip.isV4() && family_ != Option::V4) ||
|
||||
(ip.isV6() && family_ != Option::V6) ) {
|
||||
isc_throw(DhcpConfigError, "ip-address field " << ip.toText()
|
||||
<< " does not have IP address of expected family type: "
|
||||
<< (family_ == Option::V4 ? "IPv4" : "IPv6")
|
||||
<< " (" << getPosition("ip-address", relay_info) << ")");
|
||||
if (relay_elem->getType() != Element::map) {
|
||||
isc_throw(DhcpConfigError, "relay must be a map");
|
||||
}
|
||||
|
||||
// Ok, we're done with parsing. Let's store the result in the structure
|
||||
// we were given as configuration storage.
|
||||
*cfg = isc::dhcp::Network::RelayInfo(ip);
|
||||
ConstElementPtr address = relay_elem->get("ip-address");
|
||||
ConstElementPtr addresses = relay_elem->get("ip-addresses");
|
||||
|
||||
if (address && addresses) {
|
||||
isc_throw(DhcpConfigError,
|
||||
"specify either ip-address or ip-addresses, not both");
|
||||
}
|
||||
|
||||
if (!address && !addresses) {
|
||||
isc_throw(DhcpConfigError, "ip-addresses is required");
|
||||
}
|
||||
|
||||
// Create our resultant RelayInfo structure
|
||||
*relay_info = isc::dhcp::Network::RelayInfo();
|
||||
|
||||
if (address) {
|
||||
addAddress("ip-address", getString(relay_elem, "ip-address"),
|
||||
relay_elem, relay_info);
|
||||
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
|
||||
DHCPSRV_CFGMGR_RELAY_IP_ADDRESS_DEPRECATED)
|
||||
.arg(getPosition("ip-address", relay_elem));
|
||||
return;
|
||||
}
|
||||
|
||||
if (addresses->getType() != Element::list) {
|
||||
isc_throw(DhcpConfigError, "ip-addresses must be a list "
|
||||
<< " (" << getPosition("ip-addresses", relay_elem) << ")");
|
||||
}
|
||||
|
||||
BOOST_FOREACH(ConstElementPtr address_element, addresses->listValue()) {
|
||||
addAddress("ip-addresses", address_element->stringValue(),
|
||||
relay_elem, relay_info);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RelayInfoParser::addAddress(const std::string& name,
|
||||
const std::string& address_str,
|
||||
ConstElementPtr relay_elem,
|
||||
const isc::dhcp::Network::RelayInfoPtr& relay_info) {
|
||||
boost::scoped_ptr<isc::asiolink::IOAddress> ip;
|
||||
try {
|
||||
ip.reset(new isc::asiolink::IOAddress(address_str));
|
||||
} catch (const std::exception& ex) {
|
||||
isc_throw(DhcpConfigError, "address " << address_str
|
||||
<< " is not a valid: "
|
||||
<< (family_ == Option::V4 ? "IPv4" : "IPv6")
|
||||
<< "address"
|
||||
<< " (" << getPosition(name, relay_elem) << ")");
|
||||
}
|
||||
|
||||
// Check if the address family matches.
|
||||
if ((ip->isV4() && family_ != Option::V4) ||
|
||||
(ip->isV6() && family_ != Option::V6) ) {
|
||||
isc_throw(DhcpConfigError, "address " << address_str
|
||||
<< " is not a: "
|
||||
<< (family_ == Option::V4 ? "IPv4" : "IPv6")
|
||||
<< "address"
|
||||
<< " (" << getPosition(name, relay_elem) << ")");
|
||||
}
|
||||
|
||||
try {
|
||||
relay_info->addAddress(*ip);
|
||||
} catch (const std::exception& ex) {
|
||||
isc_throw(DhcpConfigError, "cannot add address: " << address_str
|
||||
<< "to relay info: " << ex.what()
|
||||
<< " (" << getPosition(name, relay_elem) << ")");
|
||||
}
|
||||
}
|
||||
|
||||
//****************************** PoolParser ********************************
|
||||
@ -431,8 +489,7 @@ SubnetConfigParser::SubnetConfigParser(uint16_t family)
|
||||
: pools_(new PoolStorage()),
|
||||
address_family_(family),
|
||||
options_(new CfgOption()) {
|
||||
string addr = family == AF_INET ? "0.0.0.0" : "::";
|
||||
relay_info_.reset(new isc::dhcp::Network::RelayInfo(IOAddress(addr)));
|
||||
relay_info_.reset(new isc::dhcp::Network::RelayInfo());
|
||||
}
|
||||
|
||||
SubnetPtr
|
||||
@ -698,7 +755,7 @@ Subnet4ConfigParser::initSubnet(data::ConstElementPtr params,
|
||||
try {
|
||||
std::string hr_mode = getString(params, "reservation-mode");
|
||||
subnet4->setHostReservationMode(hrModeFromText(hr_mode));
|
||||
} catch (const BadValue& ex) {
|
||||
} catch (const BadValue& ex) {
|
||||
isc_throw(DhcpConfigError, "Failed to process specified value "
|
||||
" of reservation-mode parameter: " << ex.what()
|
||||
<< "(" << getPosition("reservation-mode", params) << ")");
|
||||
@ -879,7 +936,7 @@ PdPoolParser::parse(PoolStoragePtr pools, ConstElementPtr pd_pool_) {
|
||||
OptionDataListParser opts_parser(AF_INET6);
|
||||
opts_parser.parse(options_, option_data);
|
||||
}
|
||||
|
||||
|
||||
ConstElementPtr user_context = pd_pool_->get("user-context");
|
||||
if (user_context) {
|
||||
user_context_ = user_context;
|
||||
@ -921,7 +978,7 @@ PdPoolParser::parse(PoolStoragePtr pools, ConstElementPtr pd_pool_) {
|
||||
pool_->allowClientClass(cclass);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (class_list) {
|
||||
const std::vector<data::ElementPtr>& classes = class_list->listValue();
|
||||
for (auto cclass = classes.cbegin();
|
||||
@ -991,7 +1048,6 @@ Subnet6ConfigParser::parse(ConstElementPtr subnet) {
|
||||
sn6ptr->setRelayInfo(*relay_info_);
|
||||
}
|
||||
|
||||
|
||||
// Parse Host Reservations for this subnet if any.
|
||||
ConstElementPtr reservations = subnet->get("reservations");
|
||||
if (reservations) {
|
||||
@ -1097,7 +1153,7 @@ Subnet6ConfigParser::initSubnet(data::ConstElementPtr params,
|
||||
try {
|
||||
std::string hr_mode = getString(params, "reservation-mode");
|
||||
subnet6->setHostReservationMode(hrModeFromText(hr_mode));
|
||||
} catch (const BadValue& ex) {
|
||||
} catch (const BadValue& ex) {
|
||||
isc_throw(DhcpConfigError, "Failed to process specified value "
|
||||
" of reservation-mode parameter: " << ex.what()
|
||||
<< "(" << getPosition("reservation-mode", params) << ")");
|
||||
@ -1214,9 +1270,9 @@ D2ClientConfigParser::parse(isc::data::ConstElementPtr client_config) {
|
||||
|
||||
std::string sender_ip_str = getString(client_config, "sender-ip");
|
||||
|
||||
uint32_t sender_port = getUint32(client_config, "sender-port");
|
||||
uint32_t sender_port = getUint32(client_config, "sender-port");
|
||||
|
||||
uint32_t max_queue_size = getUint32(client_config, "max-queue-size");
|
||||
uint32_t max_queue_size = getUint32(client_config, "max-queue-size");
|
||||
|
||||
dhcp_ddns::NameChangeProtocol ncr_protocol =
|
||||
getProtocol(client_config, "ncr-protocol");
|
||||
@ -1245,7 +1301,7 @@ D2ClientConfigParser::parse(isc::data::ConstElementPtr client_config) {
|
||||
if (client_config->contains("qualifying-suffix")) {
|
||||
qualifying_suffix = getString(client_config, "qualifying-suffix");
|
||||
found_qualifying_suffix = true;
|
||||
}
|
||||
}
|
||||
|
||||
IOAddress sender_ip(0);
|
||||
if (sender_ip_str.empty()) {
|
||||
|
@ -397,12 +397,32 @@ public:
|
||||
///
|
||||
/// The elements currently supported are:
|
||||
/// -# ip-address
|
||||
/// -# ip-addresses
|
||||
///
|
||||
/// @param cfg configuration will be stored here
|
||||
/// @param relay_info JSON structure holding relay parameters to parse
|
||||
void parse(const isc::dhcp::Network::RelayInfoPtr& cfg,
|
||||
isc::data::ConstElementPtr relay_info);
|
||||
/// Note that ip-address and ip-addresses are mutually exclusive, with
|
||||
/// former being deprecated. The use of ip-address will cause an debug
|
||||
/// log to be emitted, reminded users to switch.
|
||||
///
|
||||
/// @param relay_info configuration will be stored here
|
||||
/// @param relay_elem Element tree containing the relay and its members
|
||||
/// @throw isc::dhcp::DhcpConfigError if both or neither of ip-address
|
||||
/// and ip-addresses are specified.
|
||||
void parse(const isc::dhcp::Network::RelayInfoPtr& relay_info,
|
||||
isc::data::ConstElementPtr relay_elem);
|
||||
|
||||
/// @brief Attempts to add an IP address to list of relay addresses
|
||||
///
|
||||
/// @param name name of the element supplying the address string, (either
|
||||
/// "ip-address" or "ip-addresses")
|
||||
/// @param address string form of the IP address to add
|
||||
/// @param relay_elem parent relay element (needed for position info)
|
||||
/// @param relay_info RelayInfo to which the address should be added
|
||||
/// @throw isc::dhcp::DhcpConfigError if the address string is not a valid
|
||||
/// IP address, is an address of the wrong family, or is already in the
|
||||
/// relay address list
|
||||
void addAddress(const std::string& name, const std::string& address_str,
|
||||
isc::data::ConstElementPtr relay_elem,
|
||||
const isc::dhcp::Network::RelayInfoPtr& relay_info);
|
||||
private:
|
||||
|
||||
/// Protocol family (IPv4 or IPv6)
|
||||
|
@ -89,6 +89,15 @@ SharedNetwork4Parser::parse(const data::ConstElementPtr& shared_network_data) {
|
||||
}
|
||||
}
|
||||
|
||||
if (shared_network_data->contains("relay")) {
|
||||
auto relay_parms = shared_network_data->get("relay");
|
||||
if (relay_parms) {
|
||||
RelayInfoParser parser(Option::V4);
|
||||
Network::RelayInfoPtr relay_info(new Network::RelayInfo());
|
||||
parser.parse(relay_info, relay_parms);
|
||||
shared_network->setRelayInfo(*relay_info);
|
||||
}
|
||||
}
|
||||
} catch (const DhcpConfigError&) {
|
||||
// Position was already added
|
||||
throw;
|
||||
@ -164,6 +173,15 @@ SharedNetwork6Parser::parse(const data::ConstElementPtr& shared_network_data) {
|
||||
}
|
||||
}
|
||||
|
||||
if (shared_network_data->contains("relay")) {
|
||||
auto relay_parms = shared_network_data->get("relay");
|
||||
if (relay_parms) {
|
||||
RelayInfoParser parser(Option::V6);
|
||||
Network::RelayInfoPtr relay_info(new Network::RelayInfo());
|
||||
parser.parse(relay_info, relay_parms);
|
||||
shared_network->setRelayInfo(*relay_info);
|
||||
}
|
||||
}
|
||||
} catch (const std::exception& ex) {
|
||||
isc_throw(DhcpConfigError, ex.what() << " ("
|
||||
<< shared_network_data->getPosition() << ")");
|
||||
|
@ -231,8 +231,7 @@ Subnet4::Subnet4(const isc::asiolink::IOAddress& prefix, uint8_t length,
|
||||
isc_throw(BadValue, "Non IPv4 prefix " << prefix.toText()
|
||||
<< " specified in subnet4");
|
||||
}
|
||||
// Relay info.
|
||||
setRelayInfo(IOAddress::IPV4_ZERO_ADDRESS());
|
||||
|
||||
// Timers.
|
||||
setT1(t1);
|
||||
setT2(t2);
|
||||
@ -602,8 +601,6 @@ Subnet6::Subnet6(const isc::asiolink::IOAddress& prefix, uint8_t length,
|
||||
<< " specified in subnet6");
|
||||
}
|
||||
|
||||
// Relay info.
|
||||
setRelayInfo(RelayInfo(IOAddress::IPV6_ZERO_ADDRESS()));
|
||||
// Timers.
|
||||
setT1(t1);
|
||||
setT2(t2);
|
||||
|
@ -111,6 +111,9 @@ TEST(CfgSharedNetworks4Test, unparse) {
|
||||
SharedNetwork4Ptr network2(new SharedNetwork4("dog"));
|
||||
|
||||
network1->setIface("eth0");
|
||||
network1->addRelayAddress(IOAddress("198.16.1.1"));
|
||||
network1->addRelayAddress(IOAddress("198.16.1.2"));
|
||||
|
||||
network2->setIface("eth1");
|
||||
|
||||
CfgSharedNetworks4 cfg;
|
||||
@ -125,9 +128,7 @@ TEST(CfgSharedNetworks4Test, unparse) {
|
||||
" \"name\": \"dog\",\n"
|
||||
" \"option-data\": [ ],\n"
|
||||
" \"rebind-timer\": 0,\n"
|
||||
" \"relay\": {\n"
|
||||
" \"ip-address\": \"0.0.0.0\"\n"
|
||||
" },\n"
|
||||
" \"relay\": { \"ip-addresses\": [ ] },\n"
|
||||
" \"renew-timer\": 0,\n"
|
||||
" \"reservation-mode\": \"all\","
|
||||
" \"subnet4\": [ ],\n"
|
||||
@ -139,9 +140,7 @@ TEST(CfgSharedNetworks4Test, unparse) {
|
||||
" \"name\": \"frog\",\n"
|
||||
" \"option-data\": [ ],\n"
|
||||
" \"rebind-timer\": 0,\n"
|
||||
" \"relay\": {\n"
|
||||
" \"ip-address\": \"0.0.0.0\"\n"
|
||||
" },\n"
|
||||
" \"relay\": { \"ip-addresses\": [ \"198.16.1.1\", \"198.16.1.2\" ] },\n"
|
||||
" \"renew-timer\": 0,\n"
|
||||
" \"reservation-mode\": \"all\","
|
||||
" \"subnet4\": [ ],\n"
|
||||
|
@ -111,6 +111,8 @@ TEST(CfgSharedNetworks6Test, unparse) {
|
||||
SharedNetwork6Ptr network2(new SharedNetwork6("dog"));
|
||||
|
||||
network1->setIface("eth0");
|
||||
network1->addRelayAddress(IOAddress("2001:db8:1::1"));
|
||||
network1->addRelayAddress(IOAddress("2001:db8:1::2"));
|
||||
network2->setIface("eth1");
|
||||
|
||||
CfgSharedNetworks6 cfg;
|
||||
@ -126,9 +128,7 @@ TEST(CfgSharedNetworks6Test, unparse) {
|
||||
" \"preferred-lifetime\": 0,\n"
|
||||
" \"rapid-commit\": false,\n"
|
||||
" \"rebind-timer\": 0,\n"
|
||||
" \"relay\": {\n"
|
||||
" \"ip-address\": \"::\"\n"
|
||||
" },\n"
|
||||
" \"relay\": { \"ip-addresses\": [ ] },\n"
|
||||
" \"renew-timer\": 0,\n"
|
||||
" \"reservation-mode\": \"all\","
|
||||
" \"subnet6\": [ ],\n"
|
||||
@ -141,9 +141,7 @@ TEST(CfgSharedNetworks6Test, unparse) {
|
||||
" \"preferred-lifetime\": 0,\n"
|
||||
" \"rapid-commit\": false,\n"
|
||||
" \"rebind-timer\": 0,\n"
|
||||
" \"relay\": {\n"
|
||||
" \"ip-address\": \"::\"\n"
|
||||
" },\n"
|
||||
" \"relay\": { \"ip-addresses\": [ \"2001:db8:1::1\", \"2001:db8:1::2\" ] },\n"
|
||||
" \"renew-timer\": 0,\n"
|
||||
" \"reservation-mode\": \"all\","
|
||||
" \"subnet6\": [ ],\n"
|
||||
|
@ -414,7 +414,7 @@ TEST(CfgSubnets4Test, selectSubnetByOptionSelect) {
|
||||
|
||||
// Over relay-info too
|
||||
selector.giaddr_ = IOAddress("10.0.0.1");
|
||||
subnet2->setRelayInfo(IOAddress("10.0.0.1"));
|
||||
subnet2->addRelayAddress(IOAddress("10.0.0.1"));
|
||||
EXPECT_EQ(subnet3, cfg.selectSubnet(selector));
|
||||
selector.option_select_ = IOAddress("0.0.0.0");
|
||||
EXPECT_EQ(subnet2, cfg.selectSubnet(selector));
|
||||
@ -450,9 +450,9 @@ TEST(CfgSubnets4Test, selectSubnetByRelayAddress) {
|
||||
EXPECT_FALSE(cfg.selectSubnet(selector));
|
||||
|
||||
// Now specify relay info
|
||||
subnet1->setRelayInfo(IOAddress("10.0.0.1"));
|
||||
subnet2->setRelayInfo(IOAddress("10.0.0.2"));
|
||||
subnet3->setRelayInfo(IOAddress("10.0.0.3"));
|
||||
subnet1->addRelayAddress(IOAddress("10.0.0.1"));
|
||||
subnet2->addRelayAddress(IOAddress("10.0.0.2"));
|
||||
subnet3->addRelayAddress(IOAddress("10.0.0.3"));
|
||||
|
||||
// And try again. This time relay-info is there and should match.
|
||||
selector.giaddr_ = IOAddress("10.0.0.1");
|
||||
@ -485,9 +485,9 @@ TEST(CfgSubnets4Test, selectSharedNetworkByRelayAddressNetworkLevel) {
|
||||
|
||||
// Now specify relay info. Note that for the second subnet we specify
|
||||
// relay info on the network level.
|
||||
subnet1->setRelayInfo(IOAddress("10.0.0.1"));
|
||||
network->setRelayInfo(IOAddress("10.0.0.2"));
|
||||
subnet3->setRelayInfo(IOAddress("10.0.0.3"));
|
||||
subnet1->addRelayAddress(IOAddress("10.0.0.1"));
|
||||
network->addRelayAddress(IOAddress("10.0.0.2"));
|
||||
subnet3->addRelayAddress(IOAddress("10.0.0.3"));
|
||||
|
||||
// And try again. This time relay-info is there and should match.
|
||||
selector.giaddr_ = IOAddress("10.0.0.1");
|
||||
@ -524,9 +524,9 @@ TEST(CfgSubnets4Test, selectSharedNetworkByRelayAddressSubnetLevel) {
|
||||
|
||||
// Now specify relay info. Note that for the second subnet we specify
|
||||
// relay info on the network level.
|
||||
subnet1->setRelayInfo(IOAddress("10.0.0.1"));
|
||||
subnet2->setRelayInfo(IOAddress("10.0.0.2"));
|
||||
subnet3->setRelayInfo(IOAddress("10.0.0.3"));
|
||||
subnet1->addRelayAddress(IOAddress("10.0.0.1"));
|
||||
subnet2->addRelayAddress(IOAddress("10.0.0.2"));
|
||||
subnet3->addRelayAddress(IOAddress("10.0.0.3"));
|
||||
|
||||
// And try again. This time relay-info is there and should match.
|
||||
selector.giaddr_ = IOAddress("10.0.0.1");
|
||||
@ -737,7 +737,7 @@ TEST(CfgSubnets4Test, unparseSubnet) {
|
||||
Subnet4Ptr subnet3(new Subnet4(IOAddress("192.0.2.128"), 26, 1, 2, 3, 125));
|
||||
subnet1->allowClientClass("foo");
|
||||
subnet2->setIface("lo");
|
||||
subnet2->setRelayInfo(IOAddress("10.0.0.1"));
|
||||
subnet2->addRelayAddress(IOAddress("10.0.0.1"));
|
||||
subnet3->setIface("eth1");
|
||||
subnet3->requireClientClass("foo");
|
||||
subnet3->requireClientClass("bar");
|
||||
@ -757,13 +757,13 @@ TEST(CfgSubnets4Test, unparseSubnet) {
|
||||
" \"comment\": \"foo\",\n"
|
||||
" \"id\": 123,\n"
|
||||
" \"subnet\": \"192.0.2.0/26\",\n"
|
||||
" \"relay\": { \"ip-address\": \"0.0.0.0\" },\n"
|
||||
" \"match-client-id\": true,\n"
|
||||
" \"next-server\": \"0.0.0.0\",\n"
|
||||
" \"server-hostname\": \"\",\n"
|
||||
" \"boot-file-name\": \"\",\n"
|
||||
" \"renew-timer\": 1,\n"
|
||||
" \"rebind-timer\": 2,\n"
|
||||
" \"relay\": { \"ip-addresses\": [ ] },\n"
|
||||
" \"valid-lifetime\": 3,\n"
|
||||
" \"client-class\": \"foo\",\n"
|
||||
" \"4o6-interface\": \"\",\n"
|
||||
@ -775,7 +775,6 @@ TEST(CfgSubnets4Test, unparseSubnet) {
|
||||
"},{\n"
|
||||
" \"id\": 124,\n"
|
||||
" \"subnet\": \"192.0.2.64/26\",\n"
|
||||
" \"relay\": { \"ip-address\": \"10.0.0.1\" },\n"
|
||||
" \"interface\": \"lo\",\n"
|
||||
" \"match-client-id\": true,\n"
|
||||
" \"next-server\": \"0.0.0.0\",\n"
|
||||
@ -783,6 +782,7 @@ TEST(CfgSubnets4Test, unparseSubnet) {
|
||||
" \"boot-file-name\": \"\",\n"
|
||||
" \"renew-timer\": 1,\n"
|
||||
" \"rebind-timer\": 2,\n"
|
||||
" \"relay\": { \"ip-addresses\": [ \"10.0.0.1\" ] },\n"
|
||||
" \"valid-lifetime\": 3,\n"
|
||||
" \"4o6-interface\": \"\",\n"
|
||||
" \"4o6-interface-id\": \"\",\n"
|
||||
@ -794,7 +794,6 @@ TEST(CfgSubnets4Test, unparseSubnet) {
|
||||
"},{\n"
|
||||
" \"id\": 125,\n"
|
||||
" \"subnet\": \"192.0.2.128/26\",\n"
|
||||
" \"relay\": { \"ip-address\": \"0.0.0.0\" },\n"
|
||||
" \"interface\": \"eth1\",\n"
|
||||
" \"match-client-id\": true,\n"
|
||||
" \"next-server\": \"0.0.0.0\",\n"
|
||||
@ -802,6 +801,7 @@ TEST(CfgSubnets4Test, unparseSubnet) {
|
||||
" \"boot-file-name\": \"\",\n"
|
||||
" \"renew-timer\": 1,\n"
|
||||
" \"rebind-timer\": 2,\n"
|
||||
" \"relay\": { \"ip-addresses\": [ ] },\n"
|
||||
" \"valid-lifetime\": 3,\n"
|
||||
" \"4o6-interface\": \"\",\n"
|
||||
" \"4o6-interface-id\": \"\",\n"
|
||||
@ -840,13 +840,13 @@ TEST(CfgSubnets4Test, unparsePool) {
|
||||
"{\n"
|
||||
" \"id\": 123,\n"
|
||||
" \"subnet\": \"192.0.2.0/24\",\n"
|
||||
" \"relay\": { \"ip-address\": \"0.0.0.0\" },\n"
|
||||
" \"match-client-id\": true,\n"
|
||||
" \"next-server\": \"0.0.0.0\",\n"
|
||||
" \"server-hostname\": \"\",\n"
|
||||
" \"boot-file-name\": \"\",\n"
|
||||
" \"renew-timer\": 1,\n"
|
||||
" \"rebind-timer\": 2,\n"
|
||||
" \"relay\": { \"ip-addresses\": [ ] },\n"
|
||||
" \"valid-lifetime\": 3,\n"
|
||||
" \"4o6-interface\": \"\",\n"
|
||||
" \"4o6-interface-id\": \"\",\n"
|
||||
|
@ -132,9 +132,9 @@ TEST(CfgSubnets6Test, selectSubnetByRelayAddress) {
|
||||
EXPECT_FALSE(cfg.selectSubnet(selector));
|
||||
|
||||
// Now specify relay information.
|
||||
subnet1->setRelayInfo(IOAddress("2001:db8:ff::1"));
|
||||
subnet2->setRelayInfo(IOAddress("2001:db8:ff::2"));
|
||||
subnet3->setRelayInfo(IOAddress("2001:db8:ff::3"));
|
||||
subnet1->addRelayAddress(IOAddress("2001:db8:ff::1"));
|
||||
subnet2->addRelayAddress(IOAddress("2001:db8:ff::2"));
|
||||
subnet3->addRelayAddress(IOAddress("2001:db8:ff::3"));
|
||||
|
||||
// And try again. This time relay-info is there and should match.
|
||||
selector.first_relay_linkaddr_ = IOAddress("2001:db8:ff::1");
|
||||
@ -436,7 +436,7 @@ TEST(CfgSubnets6Test, unparseSubnet) {
|
||||
subnet1->setInterfaceId(ifaceid);
|
||||
subnet1->allowClientClass("foo");
|
||||
subnet2->setIface("lo");
|
||||
subnet2->setRelayInfo(IOAddress("2001:db8:ff::2"));
|
||||
subnet2->addRelayAddress(IOAddress("2001:db8:ff::2"));
|
||||
subnet3->setIface("eth1");
|
||||
subnet3->requireClientClass("foo");
|
||||
subnet3->requireClientClass("bar");
|
||||
@ -456,10 +456,10 @@ TEST(CfgSubnets6Test, unparseSubnet) {
|
||||
" \"comment\": \"foo\",\n"
|
||||
" \"id\": 123,\n"
|
||||
" \"subnet\": \"2001:db8:1::/48\",\n"
|
||||
" \"relay\": { \"ip-address\": \"::\" },\n"
|
||||
" \"interface-id\": \"relay.eth0\",\n"
|
||||
" \"renew-timer\": 1,\n"
|
||||
" \"rebind-timer\": 2,\n"
|
||||
" \"relay\": { \"ip-addresses\": [ ] },\n"
|
||||
" \"preferred-lifetime\": 3,\n"
|
||||
" \"valid-lifetime\": 4,\n"
|
||||
" \"rapid-commit\": false,\n"
|
||||
@ -471,10 +471,10 @@ TEST(CfgSubnets6Test, unparseSubnet) {
|
||||
"},{\n"
|
||||
" \"id\": 124,\n"
|
||||
" \"subnet\": \"2001:db8:2::/48\",\n"
|
||||
" \"relay\": { \"ip-address\": \"2001:db8:ff::2\" },\n"
|
||||
" \"interface\": \"lo\",\n"
|
||||
" \"renew-timer\": 1,\n"
|
||||
" \"rebind-timer\": 2,\n"
|
||||
" \"relay\": { \"ip-addresses\": [ \"2001:db8:ff::2\" ] },\n"
|
||||
" \"preferred-lifetime\": 3,\n"
|
||||
" \"valid-lifetime\": 4,\n"
|
||||
" \"rapid-commit\": false,\n"
|
||||
@ -486,10 +486,10 @@ TEST(CfgSubnets6Test, unparseSubnet) {
|
||||
"},{\n"
|
||||
" \"id\": 125,\n"
|
||||
" \"subnet\": \"2001:db8:3::/48\",\n"
|
||||
" \"relay\": { \"ip-address\": \"::\" },\n"
|
||||
" \"interface\": \"eth1\",\n"
|
||||
" \"renew-timer\": 1,\n"
|
||||
" \"rebind-timer\": 2,\n"
|
||||
" \"relay\": { \"ip-addresses\": [ ] },\n"
|
||||
" \"preferred-lifetime\": 3,\n"
|
||||
" \"valid-lifetime\": 4,\n"
|
||||
" \"rapid-commit\": false,\n"
|
||||
@ -531,9 +531,9 @@ TEST(CfgSubnets6Test, unparsePool) {
|
||||
"{\n"
|
||||
" \"id\": 123,\n"
|
||||
" \"subnet\": \"2001:db8:1::/48\",\n"
|
||||
" \"relay\": { \"ip-address\": \"::\" },\n"
|
||||
" \"renew-timer\": 1,\n"
|
||||
" \"rebind-timer\": 2,\n"
|
||||
" \"relay\": { \"ip-addresses\": [ ] },\n"
|
||||
" \"preferred-lifetime\": 3,\n"
|
||||
" \"valid-lifetime\": 4,\n"
|
||||
" \"rapid-commit\": false,\n"
|
||||
@ -586,9 +586,9 @@ TEST(CfgSubnets6Test, unparsePdPool) {
|
||||
"{\n"
|
||||
" \"id\": 123,\n"
|
||||
" \"subnet\": \"2001:db8:1::/48\",\n"
|
||||
" \"relay\": { \"ip-address\": \"::\" },\n"
|
||||
" \"renew-timer\": 1,\n"
|
||||
" \"rebind-timer\": 2,\n"
|
||||
" \"relay\": { \"ip-addresses\": [ ] },\n"
|
||||
" \"preferred-lifetime\": 3,\n"
|
||||
" \"valid-lifetime\": 4,\n"
|
||||
" \"rapid-commit\": false,\n"
|
||||
|
@ -2220,14 +2220,13 @@ TEST_F(ParseConfigTest, validRelayInfo4) {
|
||||
" }";
|
||||
ElementPtr json = Element::fromJSON(config_str);
|
||||
|
||||
// We need to set the default ip-address to something.
|
||||
Network::RelayInfoPtr result(new Network::RelayInfo(asiolink::IOAddress("0.0.0.0")));
|
||||
// Create an "empty" RelayInfo to hold the parsed result.
|
||||
Network::RelayInfoPtr result(new Network::RelayInfo());
|
||||
|
||||
RelayInfoParser parser(Option::V4);
|
||||
|
||||
// Subnet4 parser will pass 0.0.0.0 to the RelayInfoParser
|
||||
EXPECT_NO_THROW(parser.parse(result, json));
|
||||
EXPECT_EQ("192.0.2.1", result->addr_.toText());
|
||||
EXPECT_TRUE(result->containsAddress(IOAddress("192.0.2.1")));
|
||||
}
|
||||
|
||||
/// @brief Checks that a bogus relay info structure for IPv4 is rejected.
|
||||
@ -2253,8 +2252,8 @@ TEST_F(ParseConfigTest, bogusRelayInfo4) {
|
||||
" }";
|
||||
ElementPtr json_bogus3 = Element::fromJSON(config_str_bogus3);
|
||||
|
||||
// We need to set the default ip-address to something.
|
||||
Network::RelayInfoPtr result(new Network::RelayInfo(IOAddress::IPV4_ZERO_ADDRESS()));
|
||||
// Create an "empty" RelayInfo to hold the parsed result.
|
||||
Network::RelayInfoPtr result(new Network::RelayInfo());
|
||||
|
||||
RelayInfoParser parser(Option::V4);
|
||||
|
||||
@ -2278,13 +2277,13 @@ TEST_F(ParseConfigTest, validRelayInfo6) {
|
||||
" }";
|
||||
ElementPtr json = Element::fromJSON(config_str);
|
||||
|
||||
// We need to set the default ip-address to something.
|
||||
Network::RelayInfoPtr result(new Network::RelayInfo(asiolink::IOAddress("::")));
|
||||
// Create an "empty" RelayInfo to hold the parsed result.
|
||||
Network::RelayInfoPtr result(new Network::RelayInfo());
|
||||
|
||||
RelayInfoParser parser(Option::V6);
|
||||
// Subnet4 parser will pass :: to the RelayInfoParser
|
||||
|
||||
EXPECT_NO_THROW(parser.parse(result, json));
|
||||
EXPECT_EQ("2001:db8::1", result->addr_.toText());
|
||||
EXPECT_TRUE(result->containsAddress(IOAddress("2001:db8::1")));
|
||||
}
|
||||
|
||||
/// @brief Checks that a valid relay info structure for IPv6 can be handled
|
||||
@ -2310,8 +2309,8 @@ TEST_F(ParseConfigTest, bogusRelayInfo6) {
|
||||
" }";
|
||||
ElementPtr json_bogus3 = Element::fromJSON(config_str_bogus3);
|
||||
|
||||
// We need to set the default ip-address to something.
|
||||
Network::RelayInfoPtr result(new Network::RelayInfo(asiolink::IOAddress("::")));
|
||||
// Create an "empty" RelayInfo to hold the parsed result.
|
||||
Network::RelayInfoPtr result(new Network::RelayInfo());
|
||||
|
||||
RelayInfoParser parser(Option::V6);
|
||||
|
||||
|
@ -21,15 +21,97 @@ using namespace isc::data;
|
||||
using namespace isc::dhcp;
|
||||
|
||||
namespace {
|
||||
class SharedNetworkParserTest : public ::testing::Test {
|
||||
public:
|
||||
|
||||
/// @brief Structure for describing a single relay test scenario
|
||||
struct RelayTest {
|
||||
/// @brief Description of the test scenario, used for logging
|
||||
std::string description_;
|
||||
/// @brief JSON configuration body of the "relay" element
|
||||
std::string json_content_;
|
||||
/// @brief indicates if parsing should pass or fail
|
||||
bool should_parse_;
|
||||
/// @brief list of addresses expected after parsing
|
||||
IOAddressList addresses_;
|
||||
};
|
||||
|
||||
/// @brief virtual destructor
|
||||
virtual ~SharedNetworkParserTest(){};
|
||||
|
||||
/// @brief Fetch valid shared network configuration JSON text
|
||||
virtual std::string getWorkingConfig() const = 0;
|
||||
ElementPtr makeTestConfig(const std::string& name, const std::string& json_content) {
|
||||
// Create working config element tree
|
||||
ElementPtr config = Element::fromJSON(getWorkingConfig());
|
||||
|
||||
// Create test element contents
|
||||
ElementPtr content = Element::fromJSON(json_content);
|
||||
|
||||
// Add the test element to working config
|
||||
config->set(name, content);
|
||||
return (config);
|
||||
}
|
||||
|
||||
/// @brief Executes a single "relay" parsing scenario
|
||||
///
|
||||
/// Each test pass consists of the following steps:
|
||||
/// -# Attempt to parse the given JSON text
|
||||
/// -# If parsing is expected to fail and it does return otherwise fatal fail
|
||||
/// -# If parsing is expected to succeed, fatal fail if it does not
|
||||
/// -# Verify the network's relay address list matches the expected list
|
||||
/// in size and content.
|
||||
///
|
||||
/// @param test RelayTest which describes the test to conduct
|
||||
void relayTest(const RelayTest& test) {
|
||||
ElementPtr test_config;
|
||||
ASSERT_NO_THROW(test_config =
|
||||
makeTestConfig("relay", test.json_content_));
|
||||
|
||||
// Init our ref to a place holder
|
||||
Network4 dummy;
|
||||
Network& network = dummy;
|
||||
|
||||
// If parsing should fail, call parse expecting a throw.
|
||||
if (!test.should_parse_) {
|
||||
ASSERT_THROW(network = parseIntoNetwork(test_config), DhcpConfigError);
|
||||
// No throw so test outcome is correct, nothing else to do.
|
||||
return;
|
||||
}
|
||||
|
||||
// Should parse without error, let's see if it does.
|
||||
ASSERT_NO_THROW(network = parseIntoNetwork(test_config));
|
||||
|
||||
// It parsed, are the number of entries correct?
|
||||
ASSERT_EQ(test.addresses_.size(), network.getRelayAddresses().size());
|
||||
|
||||
// Are the expected addresses in the list?
|
||||
for (auto exp_address = test.addresses_.begin(); exp_address != test.addresses_.end();
|
||||
++exp_address) {
|
||||
EXPECT_TRUE(network.hasRelayAddress(*exp_address))
|
||||
<< " expected address: " << (*exp_address).toText() << " not found" ;
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Attempts to parse the given configuration into a shared network
|
||||
///
|
||||
/// Virtual function used by relayTest() to parse a test configuration.
|
||||
/// Implementation should not catch parsing exceptions.
|
||||
///
|
||||
/// @param test_config JSON configuration text to parse
|
||||
/// @return A reference to the Network created if parsing is successful
|
||||
virtual Network& parseIntoNetwork(ConstElementPtr test_config) = 0;
|
||||
};
|
||||
|
||||
|
||||
/// @brief Test fixture class for SharedNetwork4Parser class.
|
||||
class SharedNetwork4ParserTest : public ::testing::Test {
|
||||
class SharedNetwork4ParserTest : public SharedNetworkParserTest {
|
||||
public:
|
||||
|
||||
/// @brief Creates valid shared network configuration.
|
||||
///
|
||||
/// @return Valid shared network configuration.
|
||||
std::string getWorkingConfig() const {
|
||||
virtual std::string getWorkingConfig() const {
|
||||
std::string config = "{"
|
||||
" \"user-context\": { \"comment\": \"example\" },"
|
||||
" \"name\": \"bird\","
|
||||
@ -88,6 +170,16 @@ public:
|
||||
|
||||
return (config);
|
||||
}
|
||||
|
||||
virtual Network& parseIntoNetwork(ConstElementPtr test_config) {
|
||||
// Parse configuration.
|
||||
SharedNetwork4Parser parser;
|
||||
network_ = parser.parse(test_config);
|
||||
return (*network_);
|
||||
}
|
||||
|
||||
private:
|
||||
SharedNetwork4Ptr network_;
|
||||
};
|
||||
|
||||
// This test verifies that shared network parser for IPv4 works properly
|
||||
@ -172,14 +264,96 @@ TEST_F(SharedNetwork4ParserTest, clientClassMatchClientId) {
|
||||
EXPECT_FALSE(network->getMatchClientId());
|
||||
}
|
||||
|
||||
// This test verifies that parsing of the "relay" element.
|
||||
// It checks both valid and invalid scenarios.
|
||||
TEST_F(SharedNetwork4ParserTest, relayInfoTests) {
|
||||
|
||||
// Create the vector of test scenarios.
|
||||
std::vector<RelayTest> tests = {
|
||||
{
|
||||
"valid ip-address #1",
|
||||
"{ \"ip-address\": \"192.168.2.1\" }",
|
||||
true,
|
||||
{ asiolink::IOAddress("192.168.2.1") }
|
||||
},
|
||||
{
|
||||
"invalid ip-address #1",
|
||||
"{ \"ip-address\": \"not an address\" }",
|
||||
false,
|
||||
{ }
|
||||
},
|
||||
{
|
||||
"invalid ip-address #2",
|
||||
"{ \"ip-address\": \"2001:db8::1\" }",
|
||||
false,
|
||||
{ }
|
||||
},
|
||||
{
|
||||
"valid ip-addresses #1",
|
||||
"{ \"ip-addresses\": [ ] }",
|
||||
true,
|
||||
{}
|
||||
},
|
||||
{
|
||||
"valid ip-addresses #2",
|
||||
"{ \"ip-addresses\": [ \"192.168.2.1\" ] }",
|
||||
true,
|
||||
{ asiolink::IOAddress("192.168.2.1") }
|
||||
},
|
||||
{
|
||||
"valid ip-addresses #3",
|
||||
"{ \"ip-addresses\": [ \"192.168.2.1\", \"192.168.2.2\" ] }",
|
||||
true,
|
||||
{ asiolink::IOAddress("192.168.2.1"), asiolink::IOAddress("192.168.2.2") }
|
||||
},
|
||||
{
|
||||
"invalid ip-addresses #1",
|
||||
"{ \"ip-addresses\": [ \"not an address\" ] }",
|
||||
false,
|
||||
{ }
|
||||
},
|
||||
{
|
||||
"invalid ip-addresses #2",
|
||||
"{ \"ip-addresses\": [ \"2001:db8::1\" ] }",
|
||||
false,
|
||||
{ }
|
||||
},
|
||||
{
|
||||
"invalid both ip-address and ip-addresses",
|
||||
"{"
|
||||
" \"ip-address\": \"192.168.2.1\", "
|
||||
" \"ip-addresses\": [ \"192.168.2.1\", \"192.168.2.2\" ]"
|
||||
" }",
|
||||
false,
|
||||
{ }
|
||||
},
|
||||
{
|
||||
"invalid neither ip-address nor ip-addresses",
|
||||
"{}",
|
||||
false,
|
||||
{ }
|
||||
}
|
||||
};
|
||||
|
||||
// Iterate over the test scenarios, verifying each prescribed
|
||||
// outcome.
|
||||
for (auto test = tests.begin(); test != tests.end(); ++test) {
|
||||
{
|
||||
SCOPED_TRACE((*test).description_);
|
||||
relayTest(*test);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// @brief Test fixture class for SharedNetwork6Parser class.
|
||||
class SharedNetwork6ParserTest : public ::testing::Test {
|
||||
class SharedNetwork6ParserTest : public SharedNetworkParserTest {
|
||||
public:
|
||||
|
||||
/// @brief Creates valid shared network configuration.
|
||||
///
|
||||
/// @return Valid shared network configuration.
|
||||
std::string getWorkingConfig() const {
|
||||
virtual std::string getWorkingConfig() const {
|
||||
std::string config = "{"
|
||||
" \"name\": \"bird\","
|
||||
" \"interface\": \"eth1\","
|
||||
@ -228,6 +402,16 @@ public:
|
||||
|
||||
return (config);
|
||||
}
|
||||
|
||||
virtual Network& parseIntoNetwork(ConstElementPtr test_config) {
|
||||
// Parse configuration.
|
||||
SharedNetwork6Parser parser;
|
||||
network_ = parser.parse(test_config);
|
||||
return (*network_);
|
||||
}
|
||||
|
||||
private:
|
||||
SharedNetwork6Ptr network_;
|
||||
};
|
||||
|
||||
// This test verifies that shared network parser for IPv4 works properly
|
||||
@ -346,4 +530,85 @@ TEST_F(SharedNetwork6ParserTest, badEvalClientClasses) {
|
||||
EXPECT_THROW(network = parser.parse(config_element), DhcpConfigError);
|
||||
}
|
||||
|
||||
// This test verifies that v6 parsing of the "relay" element.
|
||||
// It checks both valid and invalid scenarios.
|
||||
TEST_F(SharedNetwork6ParserTest, relayInfoTests) {
|
||||
|
||||
// Create the vector of test scenarios.
|
||||
std::vector<RelayTest> tests = {
|
||||
{
|
||||
"valid ip-address #1",
|
||||
"{ \"ip-address\": \"2001:db8::1\" }",
|
||||
true,
|
||||
{ asiolink::IOAddress("2001:db8::1") }
|
||||
},
|
||||
{
|
||||
"invalid ip-address #1",
|
||||
"{ \"ip-address\": \"not an address\" }",
|
||||
false,
|
||||
{ }
|
||||
},
|
||||
{
|
||||
"invalid ip-address #2",
|
||||
"{ \"ip-address\": \"192.168.2.1\" }",
|
||||
false,
|
||||
{ }
|
||||
},
|
||||
{
|
||||
"valid ip-addresses #1",
|
||||
"{ \"ip-addresses\": [ ] }",
|
||||
true,
|
||||
{}
|
||||
},
|
||||
{
|
||||
"valid ip-addresses #2",
|
||||
"{ \"ip-addresses\": [ \"2001:db8::1\" ] }",
|
||||
true,
|
||||
{ asiolink::IOAddress("2001:db8::1") }
|
||||
},
|
||||
{
|
||||
"valid ip-addresses #3",
|
||||
"{ \"ip-addresses\": [ \"2001:db8::1\", \"2001:db8::2\" ] }",
|
||||
true,
|
||||
{ asiolink::IOAddress("2001:db8::1"), asiolink::IOAddress("2001:db8::2") }
|
||||
},
|
||||
{
|
||||
"invalid ip-addresses #1",
|
||||
"{ \"ip-addresses\": [ \"not an address\" ] }",
|
||||
false,
|
||||
{ }
|
||||
},
|
||||
{
|
||||
"invalid ip-addresses #2",
|
||||
"{ \"ip-addresses\": [ \"192.168.1.1\" ] }",
|
||||
false,
|
||||
{ }
|
||||
},
|
||||
{
|
||||
"invalid both ip-address and ip-addresses",
|
||||
"{"
|
||||
" \"ip-address\": \"2001:db8::1\", "
|
||||
" \"ip-addresses\": [ \"2001:db8::1\", \"2001:db8::2\" ]"
|
||||
" }",
|
||||
false,
|
||||
{ }
|
||||
},
|
||||
{
|
||||
"invalid neither ip-address nor ip-addresses",
|
||||
"{}",
|
||||
false,
|
||||
{ }
|
||||
}
|
||||
};
|
||||
|
||||
// Iterate over the test scenarios, verifying each prescribed
|
||||
// outcome.
|
||||
for (auto test = tests.begin(); test != tests.end(); ++test) {
|
||||
{
|
||||
SCOPED_TRACE((*test).description_);
|
||||
relayTest(*test);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
@ -265,6 +265,26 @@ TEST(SharedNetwork4Test, getPreferredSubnet) {
|
||||
EXPECT_EQ(subnet3->getID(), preferred->getID());
|
||||
}
|
||||
|
||||
// This test verifies operations on the network's relay list
|
||||
TEST(SharedNetwork4Test, relayInfoList) {
|
||||
SharedNetwork4Ptr network(new SharedNetwork4("frog"));
|
||||
|
||||
EXPECT_FALSE(network->hasRelays());
|
||||
EXPECT_FALSE(network->hasRelayAddress(IOAddress("192.168.2.1")));
|
||||
|
||||
// Add relay addresses to the network.
|
||||
network->addRelayAddress(IOAddress("192.168.2.1"));
|
||||
network->addRelayAddress(IOAddress("192.168.2.2"));
|
||||
network->addRelayAddress(IOAddress("192.168.2.3"));
|
||||
|
||||
// Verify we believe we have relays and we can match them accordingly.
|
||||
EXPECT_TRUE(network->hasRelays());
|
||||
EXPECT_TRUE(network->hasRelayAddress(IOAddress("192.168.2.1")));
|
||||
EXPECT_TRUE(network->hasRelayAddress(IOAddress("192.168.2.2")));
|
||||
EXPECT_TRUE(network->hasRelayAddress(IOAddress("192.168.2.3")));
|
||||
EXPECT_FALSE(network->hasRelayAddress(IOAddress("192.168.2.4")));
|
||||
}
|
||||
|
||||
// This test verifies that unparsing shared network returns valid structure.
|
||||
TEST(SharedNetwork4Test, unparse) {
|
||||
SharedNetwork4Ptr network(new SharedNetwork4("frog"));
|
||||
@ -281,10 +301,14 @@ TEST(SharedNetwork4Test, unparse) {
|
||||
data::ElementPtr ctx = data::Element::fromJSON(uc);
|
||||
network->setContext(ctx);
|
||||
network->requireClientClass("foo");
|
||||
network->addRelayAddress(IOAddress("192.168.2.1"));
|
||||
|
||||
// Add several subnets.
|
||||
Subnet4Ptr subnet1(new Subnet4(IOAddress("10.0.0.0"), 8, 10, 20, 30,
|
||||
SubnetID(1)));
|
||||
subnet1->addRelayAddress(IOAddress("10.0.0.1"));
|
||||
subnet1->addRelayAddress(IOAddress("10.0.0.2"));
|
||||
|
||||
Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.2.0"), 24, 10, 20, 30,
|
||||
SubnetID(2)));
|
||||
network->add(subnet1);
|
||||
@ -298,7 +322,7 @@ TEST(SharedNetwork4Test, unparse) {
|
||||
" \"option-data\": [ ],\n"
|
||||
" \"rebind-timer\": 150,\n"
|
||||
" \"relay\": {\n"
|
||||
" \"ip-address\": \"0.0.0.0\"\n"
|
||||
" \"ip-addresses\": [ \"192.168.2.1\" ]\n"
|
||||
" },\n"
|
||||
" \"renew-timer\": 100,\n"
|
||||
" \"require-client-classes\": [ \"foo\" ],\n"
|
||||
@ -317,7 +341,7 @@ TEST(SharedNetwork4Test, unparse) {
|
||||
" \"pools\": [ ],\n"
|
||||
" \"rebind-timer\": 20,\n"
|
||||
" \"relay\": {\n"
|
||||
" \"ip-address\": \"0.0.0.0\"\n"
|
||||
" \"ip-addresses\": [ \"10.0.0.1\", \"10.0.0.2\" ]\n"
|
||||
" },\n"
|
||||
" \"renew-timer\": 10,\n"
|
||||
" \"reservation-mode\": \"all\",\n"
|
||||
@ -337,7 +361,7 @@ TEST(SharedNetwork4Test, unparse) {
|
||||
" \"pools\": [ ],\n"
|
||||
" \"rebind-timer\": 20,\n"
|
||||
" \"relay\": {\n"
|
||||
" \"ip-address\": \"0.0.0.0\"\n"
|
||||
" \"ip-addresses\": [ ]\n"
|
||||
" },\n"
|
||||
" \"renew-timer\": 10,\n"
|
||||
" \"reservation-mode\": \"all\",\n"
|
||||
@ -658,6 +682,26 @@ TEST(SharedNetwork6Test, getPreferredSubnet) {
|
||||
EXPECT_EQ(subnet3->getID(), preferred->getID());
|
||||
}
|
||||
|
||||
// This test verifies operations on the network's relay list
|
||||
TEST(SharedNetwork6Test, relayInfoList) {
|
||||
SharedNetwork6Ptr network(new SharedNetwork6("frog"));
|
||||
|
||||
EXPECT_FALSE(network->hasRelays());
|
||||
EXPECT_FALSE(network->hasRelayAddress(IOAddress("2001:db8:2::1")));
|
||||
|
||||
// Add realy addresses to the network.
|
||||
network->addRelayAddress(IOAddress("2001:db8:2::1"));
|
||||
network->addRelayAddress(IOAddress("2001:db8:2::2"));
|
||||
network->addRelayAddress(IOAddress("2001:db8:2::3"));
|
||||
|
||||
// Verify we believe we have relays and we can match them accordingly.
|
||||
EXPECT_TRUE(network->hasRelays());
|
||||
EXPECT_TRUE(network->hasRelayAddress(IOAddress("2001:db8:2::1")));
|
||||
EXPECT_TRUE(network->hasRelayAddress(IOAddress("2001:db8:2::2")));
|
||||
EXPECT_TRUE(network->hasRelayAddress(IOAddress("2001:db8:2::3")));
|
||||
EXPECT_FALSE(network->hasRelayAddress(IOAddress("2001:db8:2::4")));
|
||||
}
|
||||
|
||||
// This test verifies that unparsing shared network returns valid structure.
|
||||
TEST(SharedNetwork6Test, unparse) {
|
||||
SharedNetwork6Ptr network(new SharedNetwork6("frog"));
|
||||
@ -673,11 +717,16 @@ TEST(SharedNetwork6Test, unparse) {
|
||||
network->setContext(ctx);
|
||||
network->requireClientClass("foo");
|
||||
|
||||
network->addRelayAddress(IOAddress("2001:db8:1::7"));
|
||||
network->addRelayAddress(IOAddress("2001:db8:1::8"));
|
||||
|
||||
// Add several subnets.
|
||||
Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"), 64, 10, 20, 30,
|
||||
40, SubnetID(1)));
|
||||
Subnet6Ptr subnet2(new Subnet6(IOAddress("3000::"), 16, 10, 20, 30, 40,
|
||||
SubnetID(2)));
|
||||
subnet2->addRelayAddress(IOAddress("2001:db8:1::8"));
|
||||
|
||||
network->add(subnet1);
|
||||
network->add(subnet2);
|
||||
|
||||
@ -689,7 +738,7 @@ TEST(SharedNetwork6Test, unparse) {
|
||||
" \"rapid-commit\": true,\n"
|
||||
" \"rebind-timer\": 150,\n"
|
||||
" \"relay\": {\n"
|
||||
" \"ip-address\": \"::\"\n"
|
||||
" \"ip-addresses\": [ \"2001:db8:1::7\", \"2001:db8:1::8\" ]\n"
|
||||
" },\n"
|
||||
" \"renew-timer\": 100,\n"
|
||||
" \"require-client-classes\": [ \"foo\" ],\n"
|
||||
@ -704,7 +753,7 @@ TEST(SharedNetwork6Test, unparse) {
|
||||
" \"rapid-commit\": false,\n"
|
||||
" \"rebind-timer\": 20,\n"
|
||||
" \"relay\": {\n"
|
||||
" \"ip-address\": \"::\"\n"
|
||||
" \"ip-addresses\": [ ]\n"
|
||||
" },\n"
|
||||
" \"renew-timer\": 10,\n"
|
||||
" \"reservation-mode\": \"all\",\n"
|
||||
@ -720,7 +769,7 @@ TEST(SharedNetwork6Test, unparse) {
|
||||
" \"rapid-commit\": false,\n"
|
||||
" \"rebind-timer\": 20,\n"
|
||||
" \"relay\": {\n"
|
||||
" \"ip-address\": \"::\"\n"
|
||||
" \"ip-addresses\": [ \"2001:db8:1::8\" ]\n"
|
||||
" },\n"
|
||||
" \"renew-timer\": 10,\n"
|
||||
" \"reservation-mode\": \"all\",\n"
|
||||
|
@ -76,7 +76,7 @@ TEST(Subnet4Test, inRange) {
|
||||
EXPECT_EQ(2000, subnet.getT2());
|
||||
EXPECT_EQ(3000, subnet.getValid());
|
||||
|
||||
EXPECT_EQ("0.0.0.0", subnet.getRelayInfo().addr_.toText());
|
||||
EXPECT_FALSE(subnet.hasRelays());
|
||||
|
||||
EXPECT_FALSE(subnet.inRange(IOAddress("192.0.0.0")));
|
||||
EXPECT_TRUE(subnet.inRange(IOAddress("192.0.2.0")));
|
||||
@ -87,15 +87,34 @@ TEST(Subnet4Test, inRange) {
|
||||
EXPECT_FALSE(subnet.inRange(IOAddress("255.255.255.255")));
|
||||
}
|
||||
|
||||
// Checks whether the relay field has sane default and if it can
|
||||
// be changed, stored and retrieved
|
||||
// Checks whether the relay list is empty by default
|
||||
// and basic operations function
|
||||
TEST(Subnet4Test, relay) {
|
||||
Subnet4 subnet(IOAddress("192.0.2.1"), 24, 1000, 2000, 3000);
|
||||
|
||||
EXPECT_EQ("0.0.0.0", subnet.getRelayInfo().addr_.toText());
|
||||
// Should be empty.
|
||||
EXPECT_FALSE(subnet.hasRelays());
|
||||
EXPECT_EQ(0, subnet.getRelayAddresses().size());
|
||||
|
||||
subnet.setRelayInfo(IOAddress("192.0.123.45"));
|
||||
EXPECT_EQ("192.0.123.45", subnet.getRelayInfo().addr_.toText());
|
||||
// Matching should fail.
|
||||
EXPECT_FALSE(subnet.hasRelayAddress(IOAddress("192.0.123.45")));
|
||||
|
||||
// Should be able to add them.
|
||||
subnet.addRelayAddress(IOAddress("192.0.123.45"));
|
||||
subnet.addRelayAddress(IOAddress("192.0.123.46"));
|
||||
|
||||
// Should not be empty.
|
||||
EXPECT_TRUE(subnet.hasRelays());
|
||||
|
||||
// Should be two in the list.
|
||||
EXPECT_EQ(2, subnet.getRelayAddresses().size());
|
||||
|
||||
// Should be able to match them if they are there.
|
||||
EXPECT_TRUE(subnet.hasRelayAddress(IOAddress("192.0.123.45")));
|
||||
EXPECT_TRUE(subnet.hasRelayAddress(IOAddress("192.0.123.46")));
|
||||
|
||||
// Should not match those that are not.
|
||||
EXPECT_FALSE(subnet.hasRelayAddress(IOAddress("192.0.123.47")));
|
||||
}
|
||||
|
||||
// Checks whether siaddr field can be set and retrieved correctly.
|
||||
@ -681,16 +700,34 @@ TEST(Subnet6Test, inRange) {
|
||||
EXPECT_FALSE(subnet.inRange(IOAddress("::")));
|
||||
}
|
||||
|
||||
// Checks whether the relay field has sane default and if it can
|
||||
// be changed, stored and retrieved
|
||||
// Checks whether the relay list is empty by default
|
||||
// and basic operations function
|
||||
TEST(Subnet6Test, relay) {
|
||||
Subnet6 subnet(IOAddress("2001:db8:1::"), 64, 1000, 2000, 3000, 4000);
|
||||
|
||||
EXPECT_EQ("::", subnet.getRelayInfo().addr_.toText());
|
||||
// Should be empty.
|
||||
EXPECT_FALSE(subnet.hasRelays());
|
||||
EXPECT_EQ(0, subnet.getRelayAddresses().size());
|
||||
|
||||
subnet.setRelayInfo(IOAddress("2001:ffff::1"));
|
||||
// Matching should fail.
|
||||
EXPECT_FALSE(subnet.hasRelayAddress(IOAddress("2001:ffff::45")));
|
||||
|
||||
EXPECT_EQ("2001:ffff::1", subnet.getRelayInfo().addr_.toText());
|
||||
// Should be able to add them.
|
||||
subnet.addRelayAddress(IOAddress("2001:ffff::45"));
|
||||
subnet.addRelayAddress(IOAddress("2001:ffff::46"));
|
||||
|
||||
// Should not be empty.
|
||||
EXPECT_TRUE(subnet.hasRelays());
|
||||
|
||||
// Should be two in the list.
|
||||
EXPECT_EQ(2, subnet.getRelayAddresses().size());
|
||||
|
||||
// Should be able to match them if they are there.
|
||||
EXPECT_TRUE(subnet.hasRelayAddress(IOAddress("2001:ffff::45")));
|
||||
EXPECT_TRUE(subnet.hasRelayAddress(IOAddress("2001:ffff::46")));
|
||||
|
||||
// Should not match those that are not.
|
||||
EXPECT_FALSE(subnet.hasRelayAddress(IOAddress("2001:ffff::47")));
|
||||
}
|
||||
|
||||
// Test checks whether the number of addresses available in the pools are
|
||||
|
@ -1,4 +1,3 @@
|
||||
// Generated 201804111443
|
||||
// A Bison parser, made by GNU Bison 3.0.4.
|
||||
|
||||
// Locations for Bison parsers in C++
|
||||
|
@ -1,4 +1,3 @@
|
||||
// Generated 201804111443
|
||||
// A Bison parser, made by GNU Bison 3.0.4.
|
||||
|
||||
// Positions for Bison parsers in C++
|
||||
|
@ -1,4 +1,3 @@
|
||||
// Generated 201804111443
|
||||
// A Bison parser, made by GNU Bison 3.0.4.
|
||||
|
||||
// Stack handling for Bison parsers in C++
|
||||
|
Loading…
x
Reference in New Issue
Block a user