Commit dd194559 authored by Francis Dupont's avatar Francis Dupont

[master] Finishing merge of trac3389a (re-detect interfaces)

parents 875f7862 91766237
1268. [func] fdupont
Kea now re-detects network interfaces every time configuration is
changed. 're-detect' parameter added to restore old behavior, if
needed.
(Trac #3389, git xxx)
1267. [bug] fdupont
Unit-tests for libdhcp now ignore ENOPROTOPT when setting
SO_REUSEPORT to improve compatibility with older RedHat versions.
......
......@@ -29,7 +29,11 @@
// 'udp' is generally better if you have only relayed traffic. Kea
// than opens up normal UDP socket and the kernel does all the
// Ethernet/IP stack processing.
"dhcp-socket-type": "udp"
"dhcp-socket-type": "udp",
// This makes interfaces to be re-detected at each (re-)configuration.
// By default it is true.
"re-detect": true
},
// We need to specify the the database used to store leases. As of
......
......@@ -16,7 +16,11 @@
{
// Kea is told to listen on ethX network interface only.
"interfaces-config": {
"interfaces": [ "ethX" ]
"interfaces": [ "ethX" ],
// This makes interfaces to be re-detected at each (re-)configuration.
// By default it is true.
"re-detect": true
},
// We need to specify the the database used to store leases. As of
......
......@@ -719,6 +719,23 @@ temporarily override a list of interface names and listen on all interfaces.
supported on the particular OS, the server will issue a warning and
fall back to use IP/UDP sockets.</para>
</note>
<para>Interfaces are re-detected at each reconfiguration. This behavior
can be disabled by setting <command>re-detect</command> value to
<userinput>false</userinput>, for instance:
<screen>
"Dhcp4": {
"interfaces-config": {
"interfaces": [ <userinput>"eth1", "eth3"</userinput> ],
"re-detect": <userinput>false</userinput>
},
...
}
</screen>
Note interfaces are not re-detected during <command>config-test</command>.
</para>
</section>
<section id="dhcpinform-unicast-issues">
......
......@@ -625,6 +625,24 @@ for MySQL and PostgreSQL databases.</para></note>
It is anticipated that this will form of usage only be used where it is desired to
temporarily override a list of interface names and listen on all interfaces.
</para>
<para>As for the DHCPv4 server binding to specific addresses and
disabling re-detection of interfaces are supported. But
<command>dhcp-socket-type</command> is not because DHCPv6 uses
UDP/IPv6 sockets only. The following example shows how to disable the
interface detection:
</para>
<screen>
"Dhcp6": {
"interfaces-config": {
"interfaces": [ <userinput>"eth1", "eth3"</userinput> ],
"re-detect": <userinput>false</userinput>
},
...
}
</screen>
</section>
<section id="ipv6-subnet-id">
......
This diff is collapsed.
......@@ -228,6 +228,15 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
}
}
\"re-detect\" {
switch(driver.ctx_) {
case isc::dhcp::Parser4Context::INTERFACES_CONFIG:
return isc::dhcp::Dhcp4Parser::make_RE_DETECT(driver.loc_);
default:
return isc::dhcp::Dhcp4Parser::make_STRING("re-detect", driver.loc_);
}
}
\"lease-database\" {
switch(driver.ctx_) {
case isc::dhcp::Parser4Context::DHCP4:
......
This diff is collapsed.
......@@ -359,66 +359,66 @@ namespace isc { namespace dhcp {
TOKEN_DHCP_SOCKET_TYPE = 268,
TOKEN_RAW = 269,
TOKEN_UDP = 270,
TOKEN_ECHO_CLIENT_ID = 271,
TOKEN_MATCH_CLIENT_ID = 272,
TOKEN_NEXT_SERVER = 273,
TOKEN_SERVER_HOSTNAME = 274,
TOKEN_BOOT_FILE_NAME = 275,
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_PORT = 286,
TOKEN_PERSIST = 287,
TOKEN_LFC_INTERVAL = 288,
TOKEN_READONLY = 289,
TOKEN_CONNECT_TIMEOUT = 290,
TOKEN_CONTACT_POINTS = 291,
TOKEN_KEYSPACE = 292,
TOKEN_VALID_LIFETIME = 293,
TOKEN_RENEW_TIMER = 294,
TOKEN_REBIND_TIMER = 295,
TOKEN_DECLINE_PROBATION_PERIOD = 296,
TOKEN_SUBNET4 = 297,
TOKEN_SUBNET_4O6_INTERFACE = 298,
TOKEN_SUBNET_4O6_INTERFACE_ID = 299,
TOKEN_SUBNET_4O6_SUBNET = 300,
TOKEN_OPTION_DEF = 301,
TOKEN_OPTION_DATA = 302,
TOKEN_NAME = 303,
TOKEN_DATA = 304,
TOKEN_CODE = 305,
TOKEN_SPACE = 306,
TOKEN_CSV_FORMAT = 307,
TOKEN_RECORD_TYPES = 308,
TOKEN_ENCAPSULATE = 309,
TOKEN_ARRAY = 310,
TOKEN_POOLS = 311,
TOKEN_POOL = 312,
TOKEN_USER_CONTEXT = 313,
TOKEN_SUBNET = 314,
TOKEN_INTERFACE = 315,
TOKEN_INTERFACE_ID = 316,
TOKEN_ID = 317,
TOKEN_RAPID_COMMIT = 318,
TOKEN_RESERVATION_MODE = 319,
TOKEN_HOST_RESERVATION_IDENTIFIERS = 320,
TOKEN_CLIENT_CLASSES = 321,
TOKEN_TEST = 322,
TOKEN_CLIENT_CLASS = 323,
TOKEN_RESERVATIONS = 324,
TOKEN_DUID = 325,
TOKEN_HW_ADDRESS = 326,
TOKEN_CIRCUIT_ID = 327,
TOKEN_CLIENT_ID = 328,
TOKEN_HOSTNAME = 329,
TOKEN_FLEX_ID = 330,
TOKEN_RE_DETECT = 271,
TOKEN_ECHO_CLIENT_ID = 272,
TOKEN_MATCH_CLIENT_ID = 273,
TOKEN_NEXT_SERVER = 274,
TOKEN_SERVER_HOSTNAME = 275,
TOKEN_BOOT_FILE_NAME = 276,
TOKEN_LEASE_DATABASE = 277,
TOKEN_HOSTS_DATABASE = 278,
TOKEN_TYPE = 279,
TOKEN_MEMFILE = 280,
TOKEN_MYSQL = 281,
TOKEN_POSTGRESQL = 282,
TOKEN_CQL = 283,
TOKEN_USER = 284,
TOKEN_PASSWORD = 285,
TOKEN_HOST = 286,
TOKEN_PORT = 287,
TOKEN_PERSIST = 288,
TOKEN_LFC_INTERVAL = 289,
TOKEN_READONLY = 290,
TOKEN_CONNECT_TIMEOUT = 291,
TOKEN_CONTACT_POINTS = 292,
TOKEN_KEYSPACE = 293,
TOKEN_VALID_LIFETIME = 294,
TOKEN_RENEW_TIMER = 295,
TOKEN_REBIND_TIMER = 296,
TOKEN_DECLINE_PROBATION_PERIOD = 297,
TOKEN_SUBNET4 = 298,
TOKEN_SUBNET_4O6_INTERFACE = 299,
TOKEN_SUBNET_4O6_INTERFACE_ID = 300,
TOKEN_SUBNET_4O6_SUBNET = 301,
TOKEN_OPTION_DEF = 302,
TOKEN_OPTION_DATA = 303,
TOKEN_NAME = 304,
TOKEN_DATA = 305,
TOKEN_CODE = 306,
TOKEN_SPACE = 307,
TOKEN_CSV_FORMAT = 308,
TOKEN_RECORD_TYPES = 309,
TOKEN_ENCAPSULATE = 310,
TOKEN_ARRAY = 311,
TOKEN_POOLS = 312,
TOKEN_POOL = 313,
TOKEN_USER_CONTEXT = 314,
TOKEN_SUBNET = 315,
TOKEN_INTERFACE = 316,
TOKEN_INTERFACE_ID = 317,
TOKEN_ID = 318,
TOKEN_RAPID_COMMIT = 319,
TOKEN_RESERVATION_MODE = 320,
TOKEN_HOST_RESERVATION_IDENTIFIERS = 321,
TOKEN_CLIENT_CLASSES = 322,
TOKEN_TEST = 323,
TOKEN_CLIENT_CLASS = 324,
TOKEN_RESERVATIONS = 325,
TOKEN_DUID = 326,
TOKEN_HW_ADDRESS = 327,
TOKEN_CIRCUIT_ID = 328,
TOKEN_CLIENT_ID = 329,
TOKEN_HOSTNAME = 330,
TOKEN_RELAY = 331,
TOKEN_IP_ADDRESS = 332,
TOKEN_HOOKS_LIBRARIES = 333,
......@@ -462,26 +462,23 @@ namespace isc { namespace dhcp {
TOKEN_OUTPUT = 371,
TOKEN_DEBUGLEVEL = 372,
TOKEN_SEVERITY = 373,
TOKEN_FLUSH = 374,
TOKEN_MAXSIZE = 375,
TOKEN_MAXVER = 376,
TOKEN_DHCP6 = 377,
TOKEN_DHCPDDNS = 378,
TOKEN_TOPLEVEL_JSON = 379,
TOKEN_TOPLEVEL_DHCP4 = 380,
TOKEN_SUB_DHCP4 = 381,
TOKEN_SUB_INTERFACES4 = 382,
TOKEN_SUB_SUBNET4 = 383,
TOKEN_SUB_POOL4 = 384,
TOKEN_SUB_RESERVATION = 385,
TOKEN_SUB_OPTION_DEF = 386,
TOKEN_SUB_OPTION_DATA = 387,
TOKEN_SUB_HOOKS_LIBRARY = 388,
TOKEN_SUB_DHCP_DDNS = 389,
TOKEN_STRING = 390,
TOKEN_INTEGER = 391,
TOKEN_FLOAT = 392,
TOKEN_BOOLEAN = 393
TOKEN_DHCP6 = 374,
TOKEN_DHCPDDNS = 375,
TOKEN_TOPLEVEL_JSON = 376,
TOKEN_TOPLEVEL_DHCP4 = 377,
TOKEN_SUB_DHCP4 = 378,
TOKEN_SUB_INTERFACES4 = 379,
TOKEN_SUB_SUBNET4 = 380,
TOKEN_SUB_POOL4 = 381,
TOKEN_SUB_RESERVATION = 382,
TOKEN_SUB_OPTION_DEF = 383,
TOKEN_SUB_OPTION_DATA = 384,
TOKEN_SUB_HOOKS_LIBRARY = 385,
TOKEN_SUB_DHCP_DDNS = 386,
TOKEN_STRING = 387,
TOKEN_INTEGER = 388,
TOKEN_FLOAT = 389,
TOKEN_BOOLEAN = 390
};
};
......@@ -652,6 +649,10 @@ namespace isc { namespace dhcp {
symbol_type
make_UDP (const location_type& l);
static inline
symbol_type
make_RE_DETECT (const location_type& l);
static inline
symbol_type
make_ECHO_CLIENT_ID (const location_type& l);
......@@ -888,10 +889,6 @@ namespace isc { namespace dhcp {
symbol_type
make_HOSTNAME (const location_type& l);
static inline
symbol_type
make_FLEX_ID (const location_type& l);
static inline
symbol_type
make_RELAY (const location_type& l);
......@@ -1064,18 +1061,6 @@ namespace isc { namespace dhcp {
symbol_type
make_SEVERITY (const location_type& l);
static inline
symbol_type
make_FLUSH (const location_type& l);
static inline
symbol_type
make_MAXSIZE (const location_type& l);
static inline
symbol_type
make_MAXVER (const location_type& l);
static inline
symbol_type
make_DHCP6 (const location_type& l);
......@@ -1349,12 +1334,12 @@ namespace isc { namespace dhcp {
enum
{
yyeof_ = 0,
yylast_ = 736, ///< Last index in yytable_.
yynnts_ = 313, ///< Number of nonterminal symbols.
yylast_ = 733, ///< Last index in yytable_.
yynnts_ = 307, ///< Number of nonterminal symbols.
yyfinal_ = 24, ///< Termination state number.
yyterror_ = 1,
yyerrcode_ = 256,
yyntokens_ = 139 ///< Number of tokens.
yyntokens_ = 136 ///< Number of tokens.
};
......@@ -1410,9 +1395,9 @@ namespace isc { namespace dhcp {
105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
135, 136, 137, 138
135
};
const unsigned int user_token_number_max_ = 393;
const unsigned int user_token_number_max_ = 390;
const token_number_type undef_token_ = 2;
if (static_cast<int>(t) <= yyeof_)
......@@ -1445,28 +1430,28 @@ namespace isc { namespace dhcp {
{
switch (other.type_get ())
{
case 152: // value
case 156: // map_value
case 194: // socket_type
case 203: // db_type
case 411: // ncr_protocol_value
case 419: // replace_client_name_value
case 149: // value
case 153: // map_value
case 191: // socket_type
case 201: // db_type
case 406: // ncr_protocol_value
case 414: // replace_client_name_value
value.copy< ElementPtr > (other.value);
break;
case 138: // "boolean"
case 135: // "boolean"
value.copy< bool > (other.value);
break;
case 137: // "floating point"
case 134: // "floating point"
value.copy< double > (other.value);
break;
case 136: // "integer"
case 133: // "integer"
value.copy< int64_t > (other.value);
break;
case 135: // "constant string"
case 132: // "constant string"
value.copy< std::string > (other.value);
break;
......@@ -1487,28 +1472,28 @@ namespace isc { namespace dhcp {
(void) v;
switch (this->type_get ())
{
case 152: // value
case 156: // map_value
case 194: // socket_type
case 203: // db_type
case 411: // ncr_protocol_value
case 419: // replace_client_name_value
case 149: // value
case 153: // map_value
case 191: // socket_type
case 201: // db_type
case 406: // ncr_protocol_value
case 414: // replace_client_name_value
value.copy< ElementPtr > (v);
break;
case 138: // "boolean"
case 135: // "boolean"
value.copy< bool > (v);
break;
case 137: // "floating point"
case 134: // "floating point"
value.copy< double > (v);
break;
case 136: // "integer"
case 133: // "integer"
value.copy< int64_t > (v);
break;
case 135: // "constant string"
case 132: // "constant string"
value.copy< std::string > (v);
break;
......@@ -1588,28 +1573,28 @@ namespace isc { namespace dhcp {
// Type destructor.
switch (yytype)
{
case 152: // value
case 156: // map_value
case 194: // socket_type
case 203: // db_type
case 411: // ncr_protocol_value
case 419: // replace_client_name_value
case 149: // value
case 153: // map_value
case 191: // socket_type
case 201: // db_type
case 406: // ncr_protocol_value
case 414: // replace_client_name_value
value.template destroy< ElementPtr > ();
break;
case 138: // "boolean"
case 135: // "boolean"
value.template destroy< bool > ();
break;
case 137: // "floating point"
case 134: // "floating point"
value.template destroy< double > ();
break;
case 136: // "integer"
case 133: // "integer"
value.template destroy< int64_t > ();
break;
case 135: // "constant string"
case 132: // "constant string"
value.template destroy< std::string > ();
break;
......@@ -1636,28 +1621,28 @@ namespace isc { namespace dhcp {
super_type::move(s);
switch (this->type_get ())
{
case 152: // value
case 156: // map_value
case 194: // socket_type
case 203: // db_type
case 411: // ncr_protocol_value
case 419: // replace_client_name_value
case 149: // value
case 153: // map_value
case 191: // socket_type
case 201: // db_type
case 406: // ncr_protocol_value
case 414: // replace_client_name_value
value.move< ElementPtr > (s.value);
break;
case 138: // "boolean"
case 135: // "boolean"
value.move< bool > (s.value);
break;
case 137: // "floating point"
case 134: // "floating point"
value.move< double > (s.value);
break;
case 136: // "integer"
case 133: // "integer"
value.move< int64_t > (s.value);
break;
case 135: // "constant string"
case 132: // "constant string"
value.move< std::string > (s.value);
break;
......@@ -1729,7 +1714,7 @@ namespace isc { namespace dhcp {
355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
365, 366, 367, 368, 369, 370, 371, 372, 373, 374,
375, 376, 377, 378, 379, 380, 381, 382, 383, 384,
385, 386, 387, 388, 389, 390, 391, 392, 393
385, 386, 387, 388, 389, 390
};
return static_cast<token_type> (yytoken_number_[type]);
}
......@@ -1818,6 +1803,12 @@ namespace isc { namespace dhcp {
return symbol_type (token::TOKEN_UDP, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_RE_DETECT (const location_type& l)
{
return symbol_type (token::TOKEN_RE_DETECT, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_ECHO_CLIENT_ID (const location_type& l)
{
......@@ -2172,12 +2163,6 @@ namespace isc { namespace dhcp {
return symbol_type (token::TOKEN_HOSTNAME, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_FLEX_ID (const location_type& l)
{
return symbol_type (token::TOKEN_FLEX_ID, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_RELAY (const location_type& l)
{
......@@ -2436,24 +2421,6 @@ namespace isc { namespace dhcp {
return symbol_type (token::TOKEN_SEVERITY, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_FLUSH (const location_type& l)
{
return symbol_type (token::TOKEN_FLUSH, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_MAXSIZE (const location_type& l)
{
return symbol_type (token::TOKEN_MAXSIZE, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_MAXVER (const location_type& l)
{
return symbol_type (token::TOKEN_MAXVER, l);
}
Dhcp4Parser::symbol_type
Dhcp4Parser::make_DHCP6 (const location_type& l)
{
......@@ -2559,7 +2526,7 @@ namespace isc { namespace dhcp {
#line 14 "dhcp4_parser.yy" // lalr1.cc:377
} } // isc::dhcp
#line 2563 "dhcp4_parser.h" // lalr1.cc:377
#line 2530 "dhcp4_parser.h" // lalr1.cc:377
......
......@@ -55,6 +55,7 @@ using namespace std;
DHCP_SOCKET_TYPE "dhcp-socket-type"
RAW "raw"
UDP "udp"
RE_DETECT "re-detect"
ECHO_CLIENT_ID "echo-client-id"
MATCH_CLIENT_ID "match-client-id"
......@@ -460,6 +461,7 @@ interfaces_config_params: interfaces_config_param
interfaces_config_param: interfaces_list
| dhcp_socket_type
| re_detect
;
sub_interfaces4: LCURLY_BRACKET {
......@@ -491,6 +493,12 @@ socket_type: RAW { $$ = ElementPtr(new StringElement("raw", ctx.loc2pos(@1))); }
| UDP { $$ = ElementPtr(new StringElement("udp", ctx.loc2pos(@1))); }
;
re_detect: RE_DETECT COLON BOOLEAN {
ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
ctx.stack_.back()->set("re-detect", b);
};
lease_database: LEASE_DATABASE {
ElementPtr i(new MapElement(ctx.loc2pos(@1)));
ctx.stack_.back()->set("lease-database", i);
......
......@@ -489,9 +489,15 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set,
}
if (config_pair.first == "interfaces-config") {
ElementPtr ifaces_cfg =
boost::const_pointer_cast<Element>(config_pair.second);
if (check_only) {
// No re-detection in check only mode
ifaces_cfg->set("re-detect", Element::create(false));
}
IfacesConfigParser parser(AF_INET);
CfgIfacePtr cfg_iface = srv_cfg->getCfgIface();
parser.parse(cfg_iface, config_pair.second);
parser.parse(cfg_iface, ifaces_cfg);
continue;
}
......
// Generated 201705171457
// Generated 201703162308
// A Bison parser, made by GNU Bison 3.0.4.
// Locations for Bison parsers in C++
......
// Generated 201705171457
// Generated 201703162308
// A Bison parser, made by GNU Bison 3.0.4.
// Positions for Bison parsers in C++
......
......@@ -75,6 +75,11 @@ const SimpleDefaults SimpleParser4::SUBNET4_DEFAULTS = {
{ "4o6-subnet", Element::string, "" },
};
/// @brief This table defines default values for interfaces for DHCPv4.
const SimpleDefaults SimpleParser4::IFACE4_DEFAULTS = {