Browse Source

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

Francis Dupont 7 years ago
parent
commit
dd19455911
41 changed files with 4970 additions and 4930 deletions
  1. 6 0
      ChangeLog
  2. 5 1
      doc/examples/kea4/advanced.json
  3. 5 1
      doc/examples/kea6/advanced.json
  4. 17 0
      doc/guide/dhcp4-srv.xml
  5. 18 0
      doc/guide/dhcp6-srv.xml
  6. 925 971
      src/bin/dhcp4/dhcp4_lexer.cc
  7. 9 0
      src/bin/dhcp4/dhcp4_lexer.ll
  8. 1139 1198
      src/bin/dhcp4/dhcp4_parser.cc
  9. 134 167
      src/bin/dhcp4/dhcp4_parser.h
  10. 8 0
      src/bin/dhcp4/dhcp4_parser.yy
  11. 7 1
      src/bin/dhcp4/json_config_parser.cc
  12. 1 1
      src/bin/dhcp4/location.hh
  13. 1 1
      src/bin/dhcp4/position.hh
  14. 12 0
      src/bin/dhcp4/simple_parser4.cc
  15. 1 0
      src/bin/dhcp4/simple_parser4.h
  16. 1 1
      src/bin/dhcp4/stack.hh
  17. 3 1
      src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc
  18. 3 0
      src/bin/dhcp4/tests/dhcp4_test_utils.cc
  19. 16 1
      src/bin/dhcp4/tests/dhcp4_test_utils.h
  20. 111 56
      src/bin/dhcp4/tests/get_config_unittest.cc
  21. 945 990
      src/bin/dhcp6/dhcp6_lexer.cc
  22. 9 0
      src/bin/dhcp6/dhcp6_lexer.ll
  23. 1251 1300
      src/bin/dhcp6/dhcp6_parser.cc
  24. 132 166
      src/bin/dhcp6/dhcp6_parser.h
  25. 18 3
      src/bin/dhcp6/dhcp6_parser.yy
  26. 7 1
      src/bin/dhcp6/json_config_parser.cc
  27. 1 1
      src/bin/dhcp6/location.hh
  28. 1 1
      src/bin/dhcp6/position.hh
  29. 12 0
      src/bin/dhcp6/simple_parser6.cc
  30. 1 0
      src/bin/dhcp6/simple_parser6.h
  31. 1 1
      src/bin/dhcp6/stack.hh
  32. 2 1
      src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc
  33. 3 0
      src/bin/dhcp6/tests/dhcp6_test_utils.cc
  34. 16 1
      src/bin/dhcp6/tests/dhcp6_test_utils.h
  35. 103 52
      src/bin/dhcp6/tests/get_config_unittest.cc
  36. 4 1
      src/lib/dhcpsrv/cfg_iface.cc
  37. 10 0
      src/lib/dhcpsrv/cfg_iface.h
  38. 13 2
      src/lib/dhcpsrv/parsers/ifaces_config_parser.cc
  39. 6 3
      src/lib/dhcpsrv/tests/cfg_iface_unittest.cc
  40. 11 6
      src/lib/dhcpsrv/tests/ifaces_config_parser_unittest.cc
  41. 2 1
      src/lib/dhcpsrv/tests/srv_config_unittest.cc

+ 6 - 0
ChangeLog

@@ -1,3 +1,9 @@
+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.

+ 5 - 1
doc/examples/kea4/advanced.json

@@ -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

+ 5 - 1
doc/examples/kea6/advanced.json

@@ -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

+ 17 - 0
doc/guide/dhcp4-srv.xml

@@ -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">

+ 18 - 0
doc/guide/dhcp6-srv.xml

@@ -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">

File diff suppressed because it is too large
+ 925 - 971
src/bin/dhcp4/dhcp4_lexer.cc


+ 9 - 0
src/bin/dhcp4/dhcp4_lexer.ll

@@ -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:

File diff suppressed because it is too large
+ 1139 - 1198
src/bin/dhcp4/dhcp4_parser.cc


+ 134 - 167
src/bin/dhcp4/dhcp4_parser.h

@@ -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
       };
     };
 
@@ -654,6 +651,10 @@ namespace isc { namespace dhcp {
 
     static inline
     symbol_type
+    make_RE_DETECT (const location_type& l);
+
+    static inline
+    symbol_type
     make_ECHO_CLIENT_ID (const location_type& l);
 
     static inline
@@ -890,10 +891,6 @@ namespace isc { namespace dhcp {
 
     static inline
     symbol_type
-    make_FLEX_ID (const location_type& l);
-
-    static inline
-    symbol_type
     make_RELAY (const location_type& l);
 
     static inline
@@ -1066,18 +1063,6 @@ namespace isc { namespace dhcp {
 
     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);
 
     static inline
@@ -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]);
   }
@@ -1819,6 +1804,12 @@ namespace isc { namespace dhcp {
   }
 
   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)
   {
     return symbol_type (token::TOKEN_ECHO_CLIENT_ID, l);
@@ -2173,12 +2164,6 @@ namespace isc { namespace dhcp {
   }
 
   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)
   {
     return symbol_type (token::TOKEN_RELAY, l);
@@ -2437,24 +2422,6 @@ namespace isc { namespace dhcp {
   }
 
   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)
   {
     return symbol_type (token::TOKEN_DHCP6, 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
 
 
 

+ 8 - 0
src/bin/dhcp4/dhcp4_parser.yy

@@ -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);

+ 7 - 1
src/bin/dhcp4/json_config_parser.cc

@@ -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;
             }
 

+ 1 - 1
src/bin/dhcp4/location.hh

@@ -1,4 +1,4 @@
-// Generated 201705171457
+// Generated 201703162308
 // A Bison parser, made by GNU Bison 3.0.4.
 
 // Locations for Bison parsers in C++

+ 1 - 1
src/bin/dhcp4/position.hh

@@ -1,4 +1,4 @@
-// Generated 201705171457
+// Generated 201703162308
 // A Bison parser, made by GNU Bison 3.0.4.
 
 // Positions for Bison parsers in C++

+ 12 - 0
src/bin/dhcp4/simple_parser4.cc

@@ -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 = {
+    { "re-detect", Element::boolean, "true" }
+};
+
 /// @brief List of parameters that can be inherited from the global to subnet4 scope.
 ///
 /// Some parameters may be defined on both global (directly in Dhcp4) and
@@ -120,6 +125,13 @@ size_t SimpleParser4::setAllDefaults(isc::data::ElementPtr global) {
         cnt += setListDefaults(subnets, SUBNET4_DEFAULTS);
     }
 
+    // Set the defaults for interfaces config
+    ConstElementPtr ifaces_cfg = global->get("interfaces-config");
+    if (ifaces_cfg) {
+        ElementPtr mutable_cfg = boost::const_pointer_cast<Element>(ifaces_cfg);
+        cnt += setDefaults(mutable_cfg, IFACE4_DEFAULTS);
+    }
+
     return (cnt);
 }
 

+ 1 - 0
src/bin/dhcp4/simple_parser4.h

@@ -41,6 +41,7 @@ public:
     static const isc::data::SimpleDefaults OPTION4_DEFAULTS;
     static const isc::data::SimpleDefaults GLOBAL4_DEFAULTS;
     static const isc::data::SimpleDefaults SUBNET4_DEFAULTS;
+    static const isc::data::SimpleDefaults IFACE4_DEFAULTS;
     static const isc::data::ParamsList INHERIT_GLOBAL_TO_SUBNET4;
 };
 

+ 1 - 1
src/bin/dhcp4/stack.hh

@@ -1,4 +1,4 @@
-// Generated 201705171457
+// Generated 201703162308
 // A Bison parser, made by GNU Bison 3.0.4.
 
 // Stack handling for Bison parsers in C++

+ 3 - 1
src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc

@@ -50,7 +50,9 @@ namespace {
 class NakedControlledDhcpv4Srv: public ControlledDhcpv4Srv {
     // "Naked" DHCPv4 server, exposes internal fields
 public:
-    NakedControlledDhcpv4Srv():ControlledDhcpv4Srv(0) { }
+    NakedControlledDhcpv4Srv():ControlledDhcpv4Srv(0) {
+        CfgMgr::instance().setFamily(AF_INET);
+    }
 
     /// Expose internal methods for the sake of testing
     using Dhcpv4Srv::receivePacket;

+ 3 - 0
src/bin/dhcp4/tests/dhcp4_test_utils.cc

@@ -608,6 +608,9 @@ Dhcpv4SrvTest::configure(const std::string& config, NakedDhcpv4Srv& srv,
     ASSERT_NO_THROW(json = parseJSON(config));
     ConstElementPtr status;
 
+    // Disable the re-detect flag
+    disableIfacesReDetect(json);
+
     // Configure the server and make sure the config is accepted
     EXPECT_NO_THROW(status = configureDhcp4Server(srv, json));
     ASSERT_TRUE(status);

+ 16 - 1
src/bin/dhcp4/tests/dhcp4_test_utils.h

@@ -479,6 +479,18 @@ public:
     NakedDhcpv4Srv srv_;
 };
 
+/// @brief Patch the server config to add interface-config/re-detect=false
+/// @param json the server config
+inline void
+disableIfacesReDetect(isc::data::ConstElementPtr json) {
+    isc::data::ConstElementPtr ifaces_cfg = json->get("interfaces-config");
+    if (ifaces_cfg) {
+        isc::data::ElementPtr mutable_cfg =
+            boost::const_pointer_cast<isc::data::Element>(ifaces_cfg);
+        mutable_cfg->set("re-detect", isc::data::Element::create(false));
+    }
+}
+
 /// @brief Runs parser in JSON mode, useful for parser testing
 ///
 /// @param in string to be parsed
@@ -503,7 +515,10 @@ parseDHCP4(const std::string& in, bool verbose = false)
 {
     try {
         isc::dhcp::Parser4Context ctx;
-        return (ctx.parseString(in, isc::dhcp::Parser4Context::SUBPARSER_DHCP4));
+        isc::data::ElementPtr json;
+        json = ctx.parseString(in, isc::dhcp::Parser4Context::SUBPARSER_DHCP4);
+        disableIfacesReDetect(json);
+        return (json);
     }
     catch (const std::exception& ex) {
         if (verbose) {

+ 111 - 56
src/bin/dhcp4/tests/get_config_unittest.cc

@@ -1584,7 +1584,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -1625,7 +1626,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -1692,7 +1694,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -1759,7 +1762,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -1826,7 +1830,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -1968,7 +1973,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2110,7 +2116,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2177,7 +2184,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2244,7 +2252,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2311,7 +2320,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2378,7 +2388,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2445,7 +2456,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2537,7 +2549,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2629,7 +2642,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2696,7 +2710,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2796,7 +2811,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2863,7 +2879,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ ]\n"
+"            \"interfaces\": [ ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2914,7 +2931,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ ]\n"
+"            \"interfaces\": [ ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2965,7 +2983,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ ]\n"
+"            \"interfaces\": [ ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3025,7 +3044,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ ]\n"
+"            \"interfaces\": [ ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3076,7 +3096,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ ]\n"
+"            \"interfaces\": [ ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3127,7 +3148,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ ]\n"
+"            \"interfaces\": [ ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3178,7 +3200,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ ]\n"
+"            \"interfaces\": [ ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3229,7 +3252,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3311,7 +3335,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3393,7 +3418,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3485,7 +3511,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3560,7 +3587,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3677,7 +3705,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3767,7 +3796,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4044,7 +4074,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4119,7 +4150,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4227,7 +4259,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4307,7 +4340,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4392,7 +4426,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"eth0\", \"eth1\" ]\n"
+"            \"interfaces\": [ \"eth0\", \"eth1\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4433,7 +4468,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\", \"eth0\", \"eth1\" ]\n"
+"            \"interfaces\": [ \"*\", \"eth0\", \"eth1\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4474,7 +4510,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4541,7 +4578,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4608,7 +4646,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4822,7 +4861,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4918,7 +4958,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ ]\n"
+"            \"interfaces\": [ ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5060,7 +5101,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5101,7 +5143,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5142,7 +5185,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5183,7 +5227,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5224,7 +5269,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5291,7 +5337,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5358,7 +5405,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5425,7 +5473,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5492,7 +5541,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5582,7 +5632,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5649,7 +5700,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5716,7 +5768,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5784,7 +5837,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5856,7 +5910,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -6166,6 +6221,6 @@ TEST_P(Dhcp4GetConfigTest, run) {
 
 /// Define the parametrized test loop
 INSTANTIATE_TEST_CASE_P(Dhcp4GetConfigTest, Dhcp4GetConfigTest,
-                        ::testing::Range(static_cast<size_t>(0), max_config_counter));
+                        ::testing::Range(0UL, max_config_counter));
 
 };

File diff suppressed because it is too large
+ 945 - 990
src/bin/dhcp6/dhcp6_lexer.cc


+ 9 - 0
src/bin/dhcp6/dhcp6_lexer.ll

@@ -418,6 +418,15 @@ ControlCharacterFill            [^"\\]|\\{JSONEscapeSequence}
     }
 }
 
+\"re-detect\" {
+    switch(driver.ctx_) {
+    case isc::dhcp::Parser6Context::INTERFACES_CONFIG:
+        return  isc::dhcp::Dhcp6Parser::make_RE_DETECT(driver.loc_);
+    default:
+        return isc::dhcp::Dhcp6Parser::make_STRING("re-detect", driver.loc_);
+    }
+}
+
 \"lease-database\" {
     switch(driver.ctx_) {
     case isc::dhcp::Parser6Context::DHCP6:

File diff suppressed because it is too large
+ 1251 - 1300
src/bin/dhcp6/dhcp6_parser.cc


+ 132 - 166
src/bin/dhcp6/dhcp6_parser.h

@@ -356,67 +356,67 @@ namespace isc { namespace dhcp {
         TOKEN_DHCP6 = 265,
         TOKEN_INTERFACES_CONFIG = 266,
         TOKEN_INTERFACES = 267,
-        TOKEN_LEASE_DATABASE = 268,
-        TOKEN_HOSTS_DATABASE = 269,
-        TOKEN_TYPE = 270,
-        TOKEN_MEMFILE = 271,
-        TOKEN_MYSQL = 272,
-        TOKEN_POSTGRESQL = 273,
-        TOKEN_CQL = 274,
-        TOKEN_USER = 275,
-        TOKEN_PASSWORD = 276,
-        TOKEN_HOST = 277,
-        TOKEN_PORT = 278,
-        TOKEN_PERSIST = 279,
-        TOKEN_LFC_INTERVAL = 280,
-        TOKEN_READONLY = 281,
-        TOKEN_CONNECT_TIMEOUT = 282,
-        TOKEN_CONTACT_POINTS = 283,
-        TOKEN_KEYSPACE = 284,
-        TOKEN_PREFERRED_LIFETIME = 285,
-        TOKEN_VALID_LIFETIME = 286,
-        TOKEN_RENEW_TIMER = 287,
-        TOKEN_REBIND_TIMER = 288,
-        TOKEN_DECLINE_PROBATION_PERIOD = 289,
-        TOKEN_SUBNET6 = 290,
-        TOKEN_OPTION_DEF = 291,
-        TOKEN_OPTION_DATA = 292,
-        TOKEN_NAME = 293,
-        TOKEN_DATA = 294,
-        TOKEN_CODE = 295,
-        TOKEN_SPACE = 296,
-        TOKEN_CSV_FORMAT = 297,
-        TOKEN_RECORD_TYPES = 298,
-        TOKEN_ENCAPSULATE = 299,
-        TOKEN_ARRAY = 300,
-        TOKEN_POOLS = 301,
-        TOKEN_POOL = 302,
-        TOKEN_PD_POOLS = 303,
-        TOKEN_PREFIX = 304,
-        TOKEN_PREFIX_LEN = 305,
-        TOKEN_EXCLUDED_PREFIX = 306,
-        TOKEN_EXCLUDED_PREFIX_LEN = 307,
-        TOKEN_DELEGATED_LEN = 308,
-        TOKEN_USER_CONTEXT = 309,
-        TOKEN_SUBNET = 310,
-        TOKEN_INTERFACE = 311,
-        TOKEN_INTERFACE_ID = 312,
-        TOKEN_ID = 313,
-        TOKEN_RAPID_COMMIT = 314,
-        TOKEN_RESERVATION_MODE = 315,
-        TOKEN_MAC_SOURCES = 316,
-        TOKEN_RELAY_SUPPLIED_OPTIONS = 317,
-        TOKEN_HOST_RESERVATION_IDENTIFIERS = 318,
-        TOKEN_CLIENT_CLASSES = 319,
-        TOKEN_TEST = 320,
-        TOKEN_CLIENT_CLASS = 321,
-        TOKEN_RESERVATIONS = 322,
-        TOKEN_IP_ADDRESSES = 323,
-        TOKEN_PREFIXES = 324,
-        TOKEN_DUID = 325,
-        TOKEN_HW_ADDRESS = 326,
-        TOKEN_HOSTNAME = 327,
-        TOKEN_FLEX_ID = 328,
+        TOKEN_RE_DETECT = 268,
+        TOKEN_LEASE_DATABASE = 269,
+        TOKEN_HOSTS_DATABASE = 270,
+        TOKEN_TYPE = 271,
+        TOKEN_MEMFILE = 272,
+        TOKEN_MYSQL = 273,
+        TOKEN_POSTGRESQL = 274,
+        TOKEN_CQL = 275,
+        TOKEN_USER = 276,
+        TOKEN_PASSWORD = 277,
+        TOKEN_HOST = 278,
+        TOKEN_PORT = 279,
+        TOKEN_PERSIST = 280,
+        TOKEN_LFC_INTERVAL = 281,
+        TOKEN_READONLY = 282,
+        TOKEN_CONNECT_TIMEOUT = 283,
+        TOKEN_CONTACT_POINTS = 284,
+        TOKEN_KEYSPACE = 285,
+        TOKEN_PREFERRED_LIFETIME = 286,
+        TOKEN_VALID_LIFETIME = 287,
+        TOKEN_RENEW_TIMER = 288,
+        TOKEN_REBIND_TIMER = 289,
+        TOKEN_DECLINE_PROBATION_PERIOD = 290,
+        TOKEN_SUBNET6 = 291,
+        TOKEN_OPTION_DEF = 292,
+        TOKEN_OPTION_DATA = 293,
+        TOKEN_NAME = 294,
+        TOKEN_DATA = 295,
+        TOKEN_CODE = 296,
+        TOKEN_SPACE = 297,
+        TOKEN_CSV_FORMAT = 298,
+        TOKEN_RECORD_TYPES = 299,
+        TOKEN_ENCAPSULATE = 300,
+        TOKEN_ARRAY = 301,
+        TOKEN_POOLS = 302,
+        TOKEN_POOL = 303,
+        TOKEN_PD_POOLS = 304,
+        TOKEN_PREFIX = 305,
+        TOKEN_PREFIX_LEN = 306,
+        TOKEN_EXCLUDED_PREFIX = 307,
+        TOKEN_EXCLUDED_PREFIX_LEN = 308,
+        TOKEN_DELEGATED_LEN = 309,
+        TOKEN_USER_CONTEXT = 310,
+        TOKEN_SUBNET = 311,
+        TOKEN_INTERFACE = 312,
+        TOKEN_INTERFACE_ID = 313,
+        TOKEN_ID = 314,
+        TOKEN_RAPID_COMMIT = 315,
+        TOKEN_RESERVATION_MODE = 316,
+        TOKEN_MAC_SOURCES = 317,
+        TOKEN_RELAY_SUPPLIED_OPTIONS = 318,
+        TOKEN_HOST_RESERVATION_IDENTIFIERS = 319,
+        TOKEN_CLIENT_CLASSES = 320,
+        TOKEN_TEST = 321,
+        TOKEN_CLIENT_CLASS = 322,
+        TOKEN_RESERVATIONS = 323,
+        TOKEN_IP_ADDRESSES = 324,
+        TOKEN_PREFIXES = 325,
+        TOKEN_DUID = 326,
+        TOKEN_HW_ADDRESS = 327,
+        TOKEN_HOSTNAME = 328,
         TOKEN_RELAY = 329,
         TOKEN_IP_ADDRESS = 330,
         TOKEN_HOOKS_LIBRARIES = 331,
@@ -469,27 +469,24 @@ namespace isc { namespace dhcp {
         TOKEN_OUTPUT = 378,
         TOKEN_DEBUGLEVEL = 379,
         TOKEN_SEVERITY = 380,
-        TOKEN_FLUSH = 381,
-        TOKEN_MAXSIZE = 382,
-        TOKEN_MAXVER = 383,
-        TOKEN_DHCP4 = 384,
-        TOKEN_DHCPDDNS = 385,
-        TOKEN_TOPLEVEL_JSON = 386,
-        TOKEN_TOPLEVEL_DHCP6 = 387,
-        TOKEN_SUB_DHCP6 = 388,
-        TOKEN_SUB_INTERFACES6 = 389,
-        TOKEN_SUB_SUBNET6 = 390,
-        TOKEN_SUB_POOL6 = 391,
-        TOKEN_SUB_PD_POOL = 392,
-        TOKEN_SUB_RESERVATION = 393,
-        TOKEN_SUB_OPTION_DEF = 394,
-        TOKEN_SUB_OPTION_DATA = 395,
-        TOKEN_SUB_HOOKS_LIBRARY = 396,
-        TOKEN_SUB_DHCP_DDNS = 397,
-        TOKEN_STRING = 398,
-        TOKEN_INTEGER = 399,
-        TOKEN_FLOAT = 400,
-        TOKEN_BOOLEAN = 401
+        TOKEN_DHCP4 = 381,
+        TOKEN_DHCPDDNS = 382,
+        TOKEN_TOPLEVEL_JSON = 383,
+        TOKEN_TOPLEVEL_DHCP6 = 384,
+        TOKEN_SUB_DHCP6 = 385,
+        TOKEN_SUB_INTERFACES6 = 386,
+        TOKEN_SUB_SUBNET6 = 387,
+        TOKEN_SUB_POOL6 = 388,
+        TOKEN_SUB_PD_POOL = 389,
+        TOKEN_SUB_RESERVATION = 390,
+        TOKEN_SUB_OPTION_DEF = 391,
+        TOKEN_SUB_OPTION_DATA = 392,
+        TOKEN_SUB_HOOKS_LIBRARY = 393,
+        TOKEN_SUB_DHCP_DDNS = 394,
+        TOKEN_STRING = 395,
+        TOKEN_INTEGER = 396,
+        TOKEN_FLOAT = 397,
+        TOKEN_BOOLEAN = 398
       };
     };
 
@@ -650,6 +647,10 @@ namespace isc { namespace dhcp {
 
     static inline
     symbol_type
+    make_RE_DETECT (const location_type& l);
+
+    static inline
+    symbol_type
     make_LEASE_DATABASE (const location_type& l);
 
     static inline
@@ -890,10 +891,6 @@ namespace isc { namespace dhcp {
 
     static inline
     symbol_type
-    make_FLEX_ID (const location_type& l);
-
-    static inline
-    symbol_type
     make_RELAY (const location_type& l);
 
     static inline
@@ -1102,18 +1099,6 @@ namespace isc { namespace dhcp {
 
     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_DHCP4 (const location_type& l);
 
     static inline
@@ -1389,12 +1374,12 @@ namespace isc { namespace dhcp {
     enum
     {
       yyeof_ = 0,
-      yylast_ = 784,     ///< Last index in yytable_.
-      yynnts_ = 328,  ///< Number of nonterminal symbols.
+      yylast_ = 785,     ///< Last index in yytable_.
+      yynnts_ = 324,  ///< Number of nonterminal symbols.
       yyfinal_ = 26, ///< Termination state number.
       yyterror_ = 1,
       yyerrcode_ = 256,
-      yyntokens_ = 147  ///< Number of tokens.
+      yyntokens_ = 144  ///< Number of tokens.
     };
 
 
@@ -1450,10 +1435,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,   139,   140,   141,   142,   143,   144,
-     145,   146
+     135,   136,   137,   138,   139,   140,   141,   142,   143
     };
-    const unsigned int user_token_number_max_ = 401;
+    const unsigned int user_token_number_max_ = 398;
     const token_number_type undef_token_ = 2;
 
     if (static_cast<int>(t) <= yyeof_)
@@ -1486,28 +1470,28 @@ namespace isc { namespace dhcp {
   {
       switch (other.type_get ())
     {
-      case 161: // value
-      case 165: // map_value
+      case 158: // value
+      case 162: // map_value
       case 206: // db_type
-      case 401: // duid_type
-      case 434: // ncr_protocol_value
-      case 442: // replace_client_name_value
+      case 398: // duid_type
+      case 431: // ncr_protocol_value
+      case 439: // replace_client_name_value
         value.copy< ElementPtr > (other.value);
         break;
 
-      case 146: // "boolean"
+      case 143: // "boolean"
         value.copy< bool > (other.value);
         break;
 
-      case 145: // "floating point"
+      case 142: // "floating point"
         value.copy< double > (other.value);
         break;
 
-      case 144: // "integer"
+      case 141: // "integer"
         value.copy< int64_t > (other.value);
         break;
 
-      case 143: // "constant string"
+      case 140: // "constant string"
         value.copy< std::string > (other.value);
         break;
 
@@ -1528,28 +1512,28 @@ namespace isc { namespace dhcp {
     (void) v;
       switch (this->type_get ())
     {
-      case 161: // value
-      case 165: // map_value
+      case 158: // value
+      case 162: // map_value
       case 206: // db_type
-      case 401: // duid_type
-      case 434: // ncr_protocol_value
-      case 442: // replace_client_name_value
+      case 398: // duid_type
+      case 431: // ncr_protocol_value
+      case 439: // replace_client_name_value
         value.copy< ElementPtr > (v);
         break;
 
-      case 146: // "boolean"
+      case 143: // "boolean"
         value.copy< bool > (v);
         break;
 
-      case 145: // "floating point"
+      case 142: // "floating point"
         value.copy< double > (v);
         break;
 
-      case 144: // "integer"
+      case 141: // "integer"
         value.copy< int64_t > (v);
         break;
 
-      case 143: // "constant string"
+      case 140: // "constant string"
         value.copy< std::string > (v);
         break;
 
@@ -1629,28 +1613,28 @@ namespace isc { namespace dhcp {
     // Type destructor.
     switch (yytype)
     {
-      case 161: // value
-      case 165: // map_value
+      case 158: // value
+      case 162: // map_value
       case 206: // db_type
-      case 401: // duid_type
-      case 434: // ncr_protocol_value
-      case 442: // replace_client_name_value
+      case 398: // duid_type
+      case 431: // ncr_protocol_value
+      case 439: // replace_client_name_value
         value.template destroy< ElementPtr > ();
         break;
 
-      case 146: // "boolean"
+      case 143: // "boolean"
         value.template destroy< bool > ();
         break;
 
-      case 145: // "floating point"
+      case 142: // "floating point"
         value.template destroy< double > ();
         break;
 
-      case 144: // "integer"
+      case 141: // "integer"
         value.template destroy< int64_t > ();
         break;
 
-      case 143: // "constant string"
+      case 140: // "constant string"
         value.template destroy< std::string > ();
         break;
 
@@ -1677,28 +1661,28 @@ namespace isc { namespace dhcp {
     super_type::move(s);
       switch (this->type_get ())
     {
-      case 161: // value
-      case 165: // map_value
+      case 158: // value
+      case 162: // map_value
       case 206: // db_type
-      case 401: // duid_type
-      case 434: // ncr_protocol_value
-      case 442: // replace_client_name_value
+      case 398: // duid_type
+      case 431: // ncr_protocol_value
+      case 439: // replace_client_name_value
         value.move< ElementPtr > (s.value);
         break;
 
-      case 146: // "boolean"
+      case 143: // "boolean"
         value.move< bool > (s.value);
         break;
 
-      case 145: // "floating point"
+      case 142: // "floating point"
         value.move< double > (s.value);
         break;
 
-      case 144: // "integer"
+      case 141: // "integer"
         value.move< int64_t > (s.value);
         break;
 
-      case 143: // "constant string"
+      case 140: // "constant string"
         value.move< std::string > (s.value);
         break;
 
@@ -1771,7 +1755,7 @@ namespace isc { namespace dhcp {
      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,   394,
-     395,   396,   397,   398,   399,   400,   401
+     395,   396,   397,   398
     };
     return static_cast<token_type> (yytoken_number_[type]);
   }
@@ -1843,6 +1827,12 @@ namespace isc { namespace dhcp {
   }
 
   Dhcp6Parser::symbol_type
+  Dhcp6Parser::make_RE_DETECT (const location_type& l)
+  {
+    return symbol_type (token::TOKEN_RE_DETECT, l);
+  }
+
+  Dhcp6Parser::symbol_type
   Dhcp6Parser::make_LEASE_DATABASE (const location_type& l)
   {
     return symbol_type (token::TOKEN_LEASE_DATABASE, l);
@@ -2203,12 +2193,6 @@ namespace isc { namespace dhcp {
   }
 
   Dhcp6Parser::symbol_type
-  Dhcp6Parser::make_FLEX_ID (const location_type& l)
-  {
-    return symbol_type (token::TOKEN_FLEX_ID, l);
-  }
-
-  Dhcp6Parser::symbol_type
   Dhcp6Parser::make_RELAY (const location_type& l)
   {
     return symbol_type (token::TOKEN_RELAY, l);
@@ -2521,24 +2505,6 @@ namespace isc { namespace dhcp {
   }
 
   Dhcp6Parser::symbol_type
-  Dhcp6Parser::make_FLUSH (const location_type& l)
-  {
-    return symbol_type (token::TOKEN_FLUSH, l);
-  }
-
-  Dhcp6Parser::symbol_type
-  Dhcp6Parser::make_MAXSIZE (const location_type& l)
-  {
-    return symbol_type (token::TOKEN_MAXSIZE, l);
-  }
-
-  Dhcp6Parser::symbol_type
-  Dhcp6Parser::make_MAXVER (const location_type& l)
-  {
-    return symbol_type (token::TOKEN_MAXVER, l);
-  }
-
-  Dhcp6Parser::symbol_type
   Dhcp6Parser::make_DHCP4 (const location_type& l)
   {
     return symbol_type (token::TOKEN_DHCP4, l);
@@ -2649,7 +2615,7 @@ namespace isc { namespace dhcp {
 
 #line 14 "dhcp6_parser.yy" // lalr1.cc:377
 } } // isc::dhcp
-#line 2653 "dhcp6_parser.h" // lalr1.cc:377
+#line 2619 "dhcp6_parser.h" // lalr1.cc:377
 
 
 

+ 18 - 3
src/bin/dhcp6/dhcp6_parser.yy

@@ -52,6 +52,7 @@ using namespace std;
   DHCP6 "Dhcp6"
   INTERFACES_CONFIG "interfaces-config"
   INTERFACES "interfaces"
+  RE_DETECT "re-detect"
 
   LEASE_DATABASE "lease-database"
   HOSTS_DATABASE "hosts-database"
@@ -453,7 +454,7 @@ interfaces_config: INTERFACES_CONFIG {
     ctx.stack_.back()->set("interfaces-config", i);
     ctx.stack_.push_back(i);
     ctx.enter(ctx.INTERFACES_CONFIG);
-} COLON LCURLY_BRACKET interface_config_map RCURLY_BRACKET {
+} COLON LCURLY_BRACKET interfaces_config_params RCURLY_BRACKET {
     ctx.stack_.pop_back();
     ctx.leave();
 };
@@ -462,11 +463,19 @@ sub_interfaces6: LCURLY_BRACKET {
     // Parse the interfaces-config map
     ElementPtr m(new MapElement(ctx.loc2pos(@1)));
     ctx.stack_.push_back(m);
-} interface_config_map RCURLY_BRACKET {
+} interfaces_config_params RCURLY_BRACKET {
     // parsing completed
 };
 
-interface_config_map: INTERFACES {
+interfaces_config_params: interfaces_config_param
+                        | interfaces_config_params COMMA interfaces_config_param
+                        ;
+
+interfaces_config_param: interfaces_list
+                       | re_detect
+                       ;
+
+interfaces_list: INTERFACES {
     ElementPtr l(new ListElement(ctx.loc2pos(@1)));
     ctx.stack_.back()->set("interfaces", l);
     ctx.stack_.push_back(l);
@@ -476,6 +485,12 @@ interface_config_map: INTERFACES {
     ctx.leave();
 };
 
+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);

+ 7 - 1
src/bin/dhcp6/json_config_parser.cc

@@ -700,9 +700,15 @@ configureDhcp6Server(Dhcpv6Srv&, 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_INET6);
                 CfgIfacePtr cfg_iface = srv_config->getCfgIface();
-                parser.parse(cfg_iface, config_pair.second);
+                parser.parse(cfg_iface, ifaces_cfg);
                 continue;
             }
 

+ 1 - 1
src/bin/dhcp6/location.hh

@@ -1,4 +1,4 @@
-// Generated 201705171457
+// Generated 201703162308
 // A Bison parser, made by GNU Bison 3.0.4.
 
 // Locations for Bison parsers in C++

+ 1 - 1
src/bin/dhcp6/position.hh

@@ -1,4 +1,4 @@
-// Generated 201705171457
+// Generated 201703162308
 // A Bison parser, made by GNU Bison 3.0.4.
 
 // Positions for Bison parsers in C++

+ 12 - 0
src/bin/dhcp6/simple_parser6.cc

@@ -72,6 +72,11 @@ const SimpleDefaults SimpleParser6::SUBNET6_DEFAULTS = {
     { "interface-id",     Element::string,  "" },
 };
 
+/// @brief This table defines default values for interfaces for DHCPv6.
+const SimpleDefaults SimpleParser6::IFACE6_DEFAULTS = {
+    { "re-detect", Element::boolean, "true" }
+};
+
 /// @brief List of parameters that can be inherited from the global to subnet6 scope.
 ///
 /// Some parameters may be defined on both global (directly in Dhcp6) and
@@ -119,6 +124,13 @@ size_t SimpleParser6::setAllDefaults(isc::data::ElementPtr global) {
         cnt += setListDefaults(subnets, SUBNET6_DEFAULTS);
     }
 
+    // Set the defaults for interfaces config
+    ConstElementPtr ifaces_cfg = global->get("interfaces-config");
+    if (ifaces_cfg) {
+        ElementPtr mutable_cfg = boost::const_pointer_cast<Element>(ifaces_cfg);
+        cnt += setDefaults(mutable_cfg, IFACE6_DEFAULTS);
+    }
+
     return (cnt);
 }
 

+ 1 - 0
src/bin/dhcp6/simple_parser6.h

@@ -42,6 +42,7 @@ public:
     static const isc::data::SimpleDefaults OPTION6_DEFAULTS;
     static const isc::data::SimpleDefaults GLOBAL6_DEFAULTS;
     static const isc::data::SimpleDefaults SUBNET6_DEFAULTS;
+    static const isc::data::SimpleDefaults IFACE6_DEFAULTS;
     static const isc::data::ParamsList INHERIT_GLOBAL_TO_SUBNET6;
 };
 

+ 1 - 1
src/bin/dhcp6/stack.hh

@@ -1,4 +1,4 @@
-// Generated 201705171457
+// Generated 201703162308
 // A Bison parser, made by GNU Bison 3.0.4.
 
 // Stack handling for Bison parsers in C++

+ 2 - 1
src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc

@@ -49,6 +49,7 @@ class NakedControlledDhcpv6Srv: public ControlledDhcpv6Srv {
     // "Naked" DHCPv6 server, exposes internal fields
 public:
     NakedControlledDhcpv6Srv():ControlledDhcpv6Srv(DHCP6_SERVER_PORT + 10000) {
+        CfgMgr::instance().setFamily(AF_INET6);
     }
 
     /// Expose internal methods for the sake of testing
@@ -674,7 +675,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, configTest) {
 
 typedef std::map<std::string, isc::data::ConstElementPtr> ElementMap;
 
-// This test checks which commands are registered by the DHCPv4 server.
+// This test checks which commands are registered by the DHCPv6 server.
 TEST_F(CtrlDhcpv6SrvTest, commandsRegistration) {
 
     ConstElementPtr list_cmds = createCommand("list-commands");

+ 3 - 0
src/bin/dhcp6/tests/dhcp6_test_utils.cc

@@ -702,6 +702,9 @@ Dhcpv6SrvTest::configure(const std::string& config, NakedDhcpv6Srv& srv) {
     ASSERT_NO_THROW(json = parseJSON(config));
     ConstElementPtr status;
 
+    // Disable the re-detect flag
+    disableIfacesReDetect(json);
+
     // Configure the server and make sure the config is accepted
     EXPECT_NO_THROW(status = configureDhcp6Server(srv, json));
     ASSERT_TRUE(status);

+ 16 - 1
src/bin/dhcp6/tests/dhcp6_test_utils.h

@@ -639,6 +639,18 @@ public:
     NakedDhcpv6Srv srv_;
 };
 
+/// @brief Patch the server config to add interface-config/re-detect=false
+/// @param json the server config
+inline void
+disableIfacesReDetect(isc::data::ConstElementPtr json) {
+    isc::data::ConstElementPtr ifaces_cfg = json->get("interfaces-config");
+    if (ifaces_cfg) {
+        isc::data::ElementPtr mutable_cfg =
+            boost::const_pointer_cast<isc::data::Element>(ifaces_cfg);
+        mutable_cfg->set("re-detect", isc::data::Element::create(false));
+    }
+}
+
 /// @brief Runs parser in JSON mode, useful for parser testing
 ///
 /// @param in string to be parsed
@@ -663,7 +675,10 @@ parseDHCP6(const std::string& in, bool verbose = false)
 {
     try {
         isc::dhcp::Parser6Context ctx;
-        return (ctx.parseString(in, isc::dhcp::Parser6Context::SUBPARSER_DHCP6));
+        isc::data::ElementPtr json;
+        json = ctx.parseString(in, isc::dhcp::Parser6Context::SUBPARSER_DHCP6);
+        disableIfacesReDetect(json);
+        return (json);
     }
     catch (const std::exception& ex) {
         if (verbose) {

+ 103 - 52
src/bin/dhcp6/tests/get_config_unittest.cc

@@ -1495,7 +1495,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -1545,7 +1546,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -1620,7 +1622,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -1767,7 +1770,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -1914,7 +1918,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2061,7 +2066,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2136,7 +2142,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2211,7 +2218,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ ]\n"
+"            \"interfaces\": [ ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2286,7 +2294,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2393,7 +2402,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2468,7 +2478,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2547,7 +2558,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2626,7 +2638,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2726,7 +2739,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2805,7 +2819,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ ]\n"
+"            \"interfaces\": [ ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2865,7 +2880,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ ]\n"
+"            \"interfaces\": [ ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2925,7 +2941,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ ]\n"
+"            \"interfaces\": [ ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -2994,7 +3011,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ ]\n"
+"            \"interfaces\": [ ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3054,7 +3072,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ ]\n"
+"            \"interfaces\": [ ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3114,7 +3133,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3204,7 +3224,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3294,7 +3315,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3394,7 +3416,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3478,7 +3501,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3603,7 +3627,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3718,7 +3743,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3846,7 +3872,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -3934,7 +3961,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4027,7 +4055,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"eth0\" ]\n"
+"            \"interfaces\": [ \"eth0\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4077,7 +4106,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\", \"eth0\", \"eth1\" ]\n"
+"            \"interfaces\": [ \"*\", \"eth0\", \"eth1\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4127,7 +4157,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4202,7 +4233,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4352,7 +4384,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4427,7 +4460,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4619,7 +4653,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4716,7 +4751,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4766,7 +4802,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4816,7 +4853,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ ]\n"
+"            \"interfaces\": [ ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -4963,7 +5001,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5013,7 +5052,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5063,7 +5103,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5113,7 +5154,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5163,7 +5205,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5227,7 +5270,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5302,7 +5346,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5377,7 +5422,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5453,7 +5499,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5534,7 +5581,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5615,7 +5663,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5694,7 +5743,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -5774,7 +5824,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ]\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
 "        },\n"
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
@@ -6100,6 +6151,6 @@ TEST_P(Dhcp6GetConfigTest, run) {
 
 /// Define the parametrized test loop
 INSTANTIATE_TEST_CASE_P(Dhcp6GetConfigTest, Dhcp6GetConfigTest,
-                        ::testing::Range(static_cast<size_t>(0), max_config_counter));
+                        ::testing::Range(0UL, max_config_counter));
 
 };

+ 4 - 1
src/lib/dhcpsrv/cfg_iface.cc

@@ -22,7 +22,7 @@ namespace dhcp {
 const char* CfgIface::ALL_IFACES_KEYWORD = "*";
 
 CfgIface::CfgIface()
-    : wildcard_used_(false), socket_type_(SOCKET_RAW) {
+    : wildcard_used_(false), socket_type_(SOCKET_RAW), re_detect_(false) {
 }
 
 void
@@ -425,6 +425,9 @@ CfgIface::toElement() const {
         result->set("dhcp-socket-type", Element::create(std::string("udp")));
     }
 
+    // Set re-detect
+    result->set("re-detect", Element::create(re_detect_));
+
     return (result);
 }
 

+ 10 - 0
src/lib/dhcpsrv/cfg_iface.h

@@ -257,6 +257,13 @@ public:
     /// @return a pointer to unparsed configuration
     virtual isc::data::ElementPtr toElement() const;
 
+    /// @brief Set the re-detect flag
+    ///
+    /// @param re_detect the new value of the flag
+    void setReDetect(bool re_detect) {
+        re_detect_ = re_detect;
+    }
+
 private:
 
     /// @brief Checks if multiple IPv4 addresses has been activated on any
@@ -330,6 +337,9 @@ private:
 
     /// @brief A type of the sockets used by the DHCP server.
     SocketType socket_type_;
+
+    /// @brief A boolean value which reflects current re-detect setting
+    bool re_detect_;
 };
 
 /// @brief A pointer to the @c CfgIface .

+ 13 - 2
src/lib/dhcpsrv/parsers/ifaces_config_parser.cc

@@ -20,7 +20,7 @@ namespace dhcp {
 
 void
 IfacesConfigParser::parseInterfacesList(const CfgIfacePtr& cfg_iface,
-                                           ConstElementPtr ifaces_list) {
+                                        ConstElementPtr ifaces_list) {
     BOOST_FOREACH(ConstElementPtr iface, ifaces_list->listValue()) {
         std::string iface_name = iface->stringValue();
         try {
@@ -41,10 +41,21 @@ void
 IfacesConfigParser::parse(const CfgIfacePtr& cfg,
                           const isc::data::ConstElementPtr& ifaces_config) {
 
-    // Get the pointer to the interface configuration.
+    // Check for re-detect before calling parseInterfacesList() 
+    bool re_detect = getBoolean(ifaces_config, "re-detect");
+    cfg->setReDetect(re_detect);
+    if (re_detect) {
+        IfaceMgr::instance().clearIfaces();
+        IfaceMgr::instance().detectIfaces();
+    }
+
     bool socket_type_specified = false;
     BOOST_FOREACH(ConfigPair element, ifaces_config->mapValue()) {
         try {
+            if (element.first == "re-detect") {
+                continue;
+            }
+
             if (element.first == "interfaces") {
                 parseInterfacesList(cfg, element.second);
                 continue;

+ 6 - 3
src/lib/dhcpsrv/tests/cfg_iface_unittest.cc

@@ -371,7 +371,8 @@ TEST_F(CfgIfaceTest, unparse) {
     
     // Check unparse
     std::string expected =
-        "{ \"interfaces\": [ \"*\", \"eth0\", \"eth1/192.0.2.3\" ] }";
+        "{ \"interfaces\": [ \"*\", \"eth0\", \"eth1/192.0.2.3\" ], "
+        "\"re-detect\": false }";
     runToElementTest<CfgIface>(expected, cfg4);
 
     // Now check IPv6
@@ -381,7 +382,8 @@ TEST_F(CfgIfaceTest, unparse) {
     EXPECT_NO_THROW(cfg6.use(AF_INET6, "eth0/2001:db8:1::1"));
 
     expected =
-        "{ \"interfaces\": [ \"*\", \"eth1\", \"eth0/2001:db8:1::1\" ] }";
+        "{ \"interfaces\": [ \"*\", \"eth1\", \"eth0/2001:db8:1::1\" ], "
+        "\"re-detect\": false }";
     runToElementTest<CfgIface>(expected, cfg6);
 }
 
@@ -402,7 +404,8 @@ TEST(CfgIfaceNoStubTest, useSocketType) {
     // Check unparse
     std::string expected = "{\n"
         " \"interfaces\": [ ],\n"
-        " \"dhcp-socket-type\": \"udp\" }";
+        " \"dhcp-socket-type\": \"udp\",\n"
+        " \"re-detect\": false }";
     runToElementTest<CfgIface>(expected, cfg);
 
     // Select raw sockets.

+ 11 - 6
src/lib/dhcpsrv/tests/ifaces_config_parser_unittest.cc

@@ -53,7 +53,8 @@ TEST_F(IfacesConfigParserTest, interfaces) {
     IfaceMgrTestConfig test_config(true);
 
     // Configuration with one interface.
-    std::string config = "{ ""\"interfaces\": [ \"eth0\" ] }";
+    std::string config =
+        "{ \"interfaces\": [ \"eth0\" ], \"re-detect\": false }";
 
     ElementPtr config_element = Element::fromJSON(config);
 
@@ -81,7 +82,7 @@ TEST_F(IfacesConfigParserTest, interfaces) {
 
     // Try similar configuration but this time add a wildcard interface
     // to see if sockets will open on all interfaces.
-    config = "{ \"interfaces\": [ \"eth0\", \"*\" ] }";
+    config = "{ \"interfaces\": [ \"eth0\", \"*\" ], \"re-detect\": false }";
     config_element = Element::fromJSON(config);
 
     cfg_iface = CfgMgr::instance().getStagingCfg()->getCfgIface();
@@ -106,7 +107,8 @@ TEST_F(IfacesConfigParserTest, socketTypeRaw) {
 
     // Configuration with a raw socket selected.
     std::string config = "{ ""\"interfaces\": [ ],"
-        " \"dhcp-socket-type\": \"raw\" }";
+        " \"dhcp-socket-type\": \"raw\","
+        " \"re-detect\": false }";
 
     ElementPtr config_element = Element::fromJSON(config);
 
@@ -132,7 +134,8 @@ TEST_F(IfacesConfigParserTest, socketTypeDatagram) {
 
     // Configuration with a datagram socket selected.
     std::string config = "{ \"interfaces\": [ ],"
-        " \"dhcp-socket-type\": \"udp\" }";
+        " \"dhcp-socket-type\": \"udp\","
+        " \"re-detect\": false }";
 
     ElementPtr config_element = Element::fromJSON(config);
 
@@ -160,14 +163,16 @@ TEST_F(IfacesConfigParserTest, socketTypeInvalid) {
     IfacesConfigParser parser4(AF_INET);
     CfgIfacePtr cfg_iface = CfgMgr::instance().getStagingCfg()->getCfgIface();
     std::string config = "{ \"interfaces\": [ ],"
-        "\"dhcp-socket-type\": \"default\" }";
+        "\"dhcp-socket-type\": \"default\","
+        " \"re-detect\": false }";
     ElementPtr config_element = Element::fromJSON(config);
     ASSERT_THROW(parser4.parse(cfg_iface, config_element), DhcpConfigError);
 
     // For DHCPv6 we don't accept any socket type.
     IfacesConfigParser parser6(AF_INET6);
     config = "{ \"interfaces\": [ ],"
-        " \"dhcp-socket-type\": \"udp\" }";
+        " \"dhcp-socket-type\": \"udp\","
+        " \"re-detect\": false }";
     config_element = Element::fromJSON(config);
     ASSERT_THROW(parser6.parse(cfg_iface, config_element), DhcpConfigError);
 }

+ 2 - 1
src/lib/dhcpsrv/tests/srv_config_unittest.cc

@@ -437,7 +437,8 @@ TEST_F(SrvConfigTest, unparse) {
 
     std::string defaults = "\"decline-probation-period\": 0,\n";
     defaults += "\"dhcp4o6-port\": 0,\n";
-    defaults += "\"interfaces-config\": { \"interfaces\": [ ] },\n";
+    defaults += "\"interfaces-config\": { \"interfaces\": [ ],\n";
+    defaults += " \"re-detect\": false },\n";
     defaults += "\"option-def\": [ ],\n";
     defaults += "\"option-data\": [ ],\n";
     defaults += "\"expired-leases-processing\": ";