Browse Source

[master] Added subnet manipulation support

    Merge branch 'trac5314'
Thomas Markwalder 7 years ago
parent
commit
894aeb048b

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

@@ -1640,7 +1640,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -1708,7 +1707,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -1776,7 +1774,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -1844,7 +1841,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -1869,7 +1865,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 2,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -1894,7 +1889,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 3,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -1919,7 +1913,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 4,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -1987,7 +1980,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1024,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -2012,7 +2004,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 100,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -2037,7 +2028,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -2062,7 +2052,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 34,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -2130,7 +2119,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"1.2.3.4\",\n"
 "                \"option-data\": [ ],\n"
@@ -2198,7 +2186,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"1.2.3.4\",\n"
 "                \"option-data\": [ ],\n"
@@ -2266,7 +2253,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"1.2.3.4\",\n"
 "                \"option-data\": [ ],\n"
@@ -2334,7 +2320,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -2402,7 +2387,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -2470,7 +2454,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -2495,7 +2478,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 2,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": false,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -2563,7 +2545,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": false,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -2588,7 +2569,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 2,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -2656,7 +2636,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -2724,7 +2703,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -2753,7 +2731,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 2,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -2825,7 +2802,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -3283,7 +3259,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -3351,7 +3326,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [\n"
@@ -3463,7 +3437,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -3662,7 +3635,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -3739,7 +3711,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [\n"
@@ -3824,7 +3795,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [\n"
@@ -3858,7 +3828,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 2,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [\n"
@@ -3935,7 +3904,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -4020,7 +3988,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -4232,7 +4199,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -4315,7 +4281,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -4402,7 +4367,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -4554,7 +4518,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -4622,7 +4585,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -4690,7 +4652,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 123,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -4715,7 +4676,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 234,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -4795,7 +4755,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 542,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -4921,7 +4880,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 234,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -5009,7 +4967,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -5034,7 +4991,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 2,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -5059,7 +5015,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 3,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -5084,7 +5039,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 4,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -5320,7 +5274,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -5388,7 +5341,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"2001:db8::123/45\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -5456,7 +5408,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -5524,7 +5475,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"2001:db8::543/21\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -5592,7 +5542,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"vlan123\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -5683,7 +5632,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -5751,7 +5699,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -5819,7 +5766,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -5888,7 +5834,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"
@@ -5961,7 +5906,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"match-client-id\": true,\n"
 "                \"next-server\": \"0.0.0.0\",\n"
 "                \"option-data\": [ ],\n"

+ 0 - 126
src/bin/dhcp6/tests/get_config_unittest.cc

@@ -1568,8 +1568,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -1644,8 +1642,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -1668,8 +1664,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            },\n"
 "            {\n"
 "                \"id\": 2,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -1692,8 +1686,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            },\n"
 "            {\n"
 "                \"id\": 3,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -1716,8 +1708,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            },\n"
 "            {\n"
 "                \"id\": 4,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -1792,8 +1782,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1024,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -1816,8 +1804,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            },\n"
 "            {\n"
 "                \"id\": 100,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -1840,8 +1826,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            },\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -1864,8 +1848,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            },\n"
 "            {\n"
 "                \"id\": 34,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -1940,8 +1922,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -1964,8 +1944,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            },\n"
 "            {\n"
 "                \"id\": 2,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -1988,8 +1966,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            },\n"
 "            {\n"
 "                \"id\": 3,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -2012,8 +1988,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            },\n"
 "            {\n"
 "                \"id\": 4,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -2088,8 +2062,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -2165,7 +2137,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            {\n"
 "                \"id\": 1,\n"
 "                \"interface\": \"eth0\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -2240,7 +2211,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
 "                \"interface-id\": \"foobar\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
@@ -2316,8 +2286,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -2344,8 +2312,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            },\n"
 "            {\n"
 "                \"id\": 2,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -2424,8 +2390,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -2500,14 +2464,10 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [\n"
 "                    {\n"
 "                        \"delegated-len\": 128,\n"
-"                        \"excluded-prefix\": \"::\",\n"
-"                        \"excluded-prefix-len\": 0,\n"
 "                        \"option-data\": [ ],\n"
 "                        \"prefix\": \"2001:db8:1::\",\n"
 "                        \"prefix-len\": 64\n"
@@ -2580,8 +2540,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [\n"
 "                    {\n"
@@ -2660,30 +2618,22 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [\n"
 "                    {\n"
 "                        \"delegated-len\": 80,\n"
-"                        \"excluded-prefix\": \"::\",\n"
-"                        \"excluded-prefix-len\": 0,\n"
 "                        \"option-data\": [ ],\n"
 "                        \"prefix\": \"2001:db8:1:1::\",\n"
 "                        \"prefix-len\": 72\n"
 "                    },\n"
 "                    {\n"
 "                        \"delegated-len\": 88,\n"
-"                        \"excluded-prefix\": \"::\",\n"
-"                        \"excluded-prefix-len\": 0,\n"
 "                        \"option-data\": [ ],\n"
 "                        \"prefix\": \"2001:db8:1:2::\",\n"
 "                        \"prefix-len\": 72\n"
 "                    },\n"
 "                    {\n"
 "                        \"delegated-len\": 96,\n"
-"                        \"excluded-prefix\": \"::\",\n"
-"                        \"excluded-prefix-len\": 0,\n"
 "                        \"option-data\": [ ],\n"
 "                        \"prefix\": \"3000:1:3::\",\n"
 "                        \"prefix-len\": 72\n"
@@ -2761,14 +2711,10 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [\n"
 "                    {\n"
 "                        \"delegated-len\": 64,\n"
-"                        \"excluded-prefix\": \"::\",\n"
-"                        \"excluded-prefix-len\": 0,\n"
 "                        \"option-data\": [ ],\n"
 "                        \"prefix\": \"2001:db8:1::\",\n"
 "                        \"prefix-len\": 64\n"
@@ -3172,8 +3118,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -3248,8 +3192,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [\n"
 "                    {\n"
 "                        \"always-send\": false,\n"
@@ -3368,8 +3310,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -3584,8 +3524,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -3660,8 +3598,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [\n"
 "                    {\n"
 "                        \"always-send\": false,\n"
@@ -3693,8 +3629,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            },\n"
 "            {\n"
 "                \"id\": 2,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [\n"
 "                    {\n"
 "                        \"always-send\": false,\n"
@@ -3778,14 +3712,10 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [\n"
 "                    {\n"
 "                        \"delegated-len\": 64,\n"
-"                        \"excluded-prefix\": \"::\",\n"
-"                        \"excluded-prefix-len\": 0,\n"
 "                        \"option-data\": [\n"
 "                            {\n"
 "                                \"always-send\": false,\n"
@@ -3801,8 +3731,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                    },\n"
 "                    {\n"
 "                        \"delegated-len\": 64,\n"
-"                        \"excluded-prefix\": \"::\",\n"
-"                        \"excluded-prefix-len\": 0,\n"
 "                        \"option-data\": [\n"
 "                            {\n"
 "                                \"always-send\": false,\n"
@@ -3926,8 +3854,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -4021,8 +3947,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -4199,8 +4123,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -4276,8 +4198,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            {\n"
 "                \"client-class\": \"alpha\",\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -4301,8 +4221,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            {\n"
 "                \"client-class\": \"beta\",\n"
 "                \"id\": 2,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -4326,8 +4244,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            {\n"
 "                \"client-class\": \"gamma\",\n"
 "                \"id\": 3,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -4350,8 +4266,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            },\n"
 "            {\n"
 "                \"id\": 4,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -4426,8 +4340,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -4502,8 +4414,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 123,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -4526,8 +4436,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            },\n"
 "            {\n"
 "                \"id\": 234,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [ ],\n"
@@ -4596,8 +4504,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            },\n"
 "            {\n"
 "                \"id\": 542,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [ ],\n"
@@ -4711,8 +4617,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 234,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [ ],\n"
@@ -4902,8 +4806,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -4926,8 +4828,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            },\n"
 "            {\n"
 "                \"id\": 2,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -4950,8 +4850,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            },\n"
 "            {\n"
 "                \"id\": 3,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -4974,8 +4872,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            },\n"
 "            {\n"
 "                \"id\": 4,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -5319,8 +5215,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -5395,8 +5289,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -5471,8 +5363,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -5548,8 +5438,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -5630,8 +5518,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -5712,14 +5598,10 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [\n"
 "                    {\n"
 "                        \"delegated-len\": 64,\n"
-"                        \"excluded-prefix\": \"::\",\n"
-"                        \"excluded-prefix-len\": 0,\n"
 "                        \"option-data\": [ ],\n"
 "                        \"prefix\": \"2001:db8::\",\n"
 "                        \"prefix-len\": 56\n"
@@ -5792,14 +5674,10 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [\n"
 "                    {\n"
 "                        \"delegated-len\": 64,\n"
-"                        \"excluded-prefix\": \"::\",\n"
-"                        \"excluded-prefix-len\": 0,\n"
 "                        \"option-data\": [ ],\n"
 "                        \"prefix\": \"2001:db8::\",\n"
 "                        \"prefix-len\": 56,\n"
@@ -5873,14 +5751,10 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
-"                \"interface\": \"\",\n"
-"                \"interface-id\": \"\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [\n"
 "                    {\n"
 "                        \"delegated-len\": 64,\n"
-"                        \"excluded-prefix\": \"::\",\n"
-"                        \"excluded-prefix-len\": 0,\n"
 "                        \"option-data\": [ ],\n"
 "                        \"prefix\": \"2001:db8::\",\n"
 "                        \"prefix-len\": 56,\n"

+ 9 - 12
src/lib/config/hooked_command_mgr.cc

@@ -7,6 +7,7 @@
 #include <cc/command_interpreter.h>
 #include <config/hooked_command_mgr.h>
 #include <config/config_log.h>
+#include <hooks/callout_handle.h>
 #include <hooks/hooks_manager.h>
 #include <hooks/server_hooks.h>
 #include <boost/pointer_cast.hpp>
@@ -19,7 +20,7 @@ namespace isc {
 namespace config {
 
 HookedCommandMgr::HookedCommandMgr()
-    : BaseCommandMgr(), callout_handle_(HooksManager::createCalloutHandle()) {
+    : BaseCommandMgr() {
 }
 
 bool
@@ -31,25 +32,25 @@ HookedCommandMgr::delegateCommandToHookLibrary(const std::string& cmd_name,
     ConstElementPtr hook_response;
     if (HooksManager::commandHandlersPresent(cmd_name)) {
 
-        callout_handle_ = HooksManager::createCalloutHandle();
+        CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
 
         // Set status to normal.
-        callout_handle_->setStatus(CalloutHandle::NEXT_STEP_CONTINUE);
+        callout_handle->setStatus(CalloutHandle::NEXT_STEP_CONTINUE);
 
         // Delete previously set arguments.
-        callout_handle_->deleteAllArguments();
+        callout_handle->deleteAllArguments();
 
         ConstElementPtr command = original_cmd ? original_cmd :
             createCommand(cmd_name, params);
 
         // And pass it to the hook library.
-        callout_handle_->setArgument("command", command);
-        callout_handle_->setArgument("response", hook_response);
+        callout_handle->setArgument("command", command);
+        callout_handle->setArgument("response", hook_response);
 
-        HooksManager::callCommandHandlers(cmd_name, *callout_handle_);
+        HooksManager::callCommandHandlers(cmd_name, *callout_handle);
 
         // The callouts should set the response.
-        callout_handle_->getArgument("response", hook_response);
+        callout_handle->getArgument("response", hook_response);
 
         answer = boost::const_pointer_cast<Element>(hook_response);
 
@@ -63,10 +64,6 @@ ConstElementPtr
 HookedCommandMgr::handleCommand(const std::string& cmd_name,
                                 const ConstElementPtr& params,
                                 const ConstElementPtr& original_cmd) {
-    if (!callout_handle_) {
-        isc_throw(Unexpected, "callout handle not configured for the Command "
-                  "Manager: this is a programming error");
-    }
 
     // The 'list-commands' is a special case. Hook libraries do not implement
     // this command. We determine what commands are supported by the hook

+ 0 - 10
src/lib/config/hooked_command_mgr.h

@@ -9,7 +9,6 @@
 
 #include <cc/data.h>
 #include <config/base_command_mgr.h>
-#include <hooks/callout_handle.h>
 
 namespace isc {
 namespace config {
@@ -47,13 +46,6 @@ public:
 
 protected:
 
-    /// @brief Returns callout handle to the derived class.
-    ///
-    /// @return const pointer to the callout handle.
-    const isc::hooks::CalloutHandlePtr& getCalloutHandle() const {
-        return (callout_handle_);
-    }
-
     /// @brief Handles the command within the hooks libraries.
     ///
     /// This method checks if the hooks libraries are installed which implement
@@ -91,8 +83,6 @@ protected:
                   const isc::data::ConstElementPtr& params,
                   const isc::data::ConstElementPtr& original_cmd);
 
-    /// @brief Pointer to a callout handle used by this class.
-    isc::hooks::CalloutHandlePtr callout_handle_;
 };
 
 } // end of namespace isc::config

+ 15 - 100
src/lib/dhcpsrv/cfg_subnets4.cc

@@ -34,6 +34,20 @@ CfgSubnets4::add(const Subnet4Ptr& subnet) {
     subnets_.push_back(subnet);
 }
 
+ConstSubnet4Ptr
+CfgSubnets4::getBySubnetId(const SubnetID& subnet_id) const {
+    const auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
+    auto subnet_it = index.find(subnet_id);
+    return ((subnet_it != index.cend()) ? (*subnet_it) : ConstSubnet4Ptr());
+}
+
+ConstSubnet4Ptr
+CfgSubnets4::getByPrefix(const std::string& subnet_text) const {
+    const auto& index = subnets_.get<SubnetPrefixIndexTag>();
+    auto subnet_it = index.find(subnet_text);
+    return ((subnet_it != index.cend()) ? (*subnet_it) : ConstSubnet4Ptr());
+}
+
 Subnet4Ptr
 CfgSubnets4::selectSubnet4o6(const SubnetSelector& selector) const {
 
@@ -297,106 +311,7 @@ CfgSubnets4::toElement() const {
     // Iterate subnets
     for (Subnet4Collection::const_iterator subnet = subnets_.cbegin();
          subnet != subnets_.cend(); ++subnet) {
-        // Prepare the map
-        ElementPtr map = Element::createMap();
-        // Set subnet id
-        SubnetID id = (*subnet)->getID();
-        map->set("id", Element::create(static_cast<long long>(id)));
-        // Set relay info
-        const Subnet::RelayInfo& relay_info = (*subnet)->getRelayInfo();
-        ElementPtr relay = Element::createMap();
-        relay->set("ip-address", Element::create(relay_info.addr_.toText()));
-        map->set("relay", relay);
-        // Set subnet
-        map->set("subnet", Element::create((*subnet)->toText()));
-        // Set interface
-        const std::string& iface = (*subnet)->getIface();
-        map->set("interface", Element::create(iface));
-        // Set renew-timer
-        map->set("renew-timer",
-                 Element::create(static_cast<long long>
-                                 ((*subnet)->getT1().get())));
-        // Set rebind-timer
-        map->set("rebind-timer",
-                 Element::create(static_cast<long long>
-                                 ((*subnet)->getT2().get())));
-        // Set valid-lifetime
-        map->set("valid-lifetime",
-                 Element::create(static_cast<long long>
-                                 ((*subnet)->getValid().get())));
-        // Set pools
-        const PoolCollection& pools = (*subnet)->getPools(Lease::TYPE_V4);
-        ElementPtr pool_list = Element::createList();
-        for (PoolCollection::const_iterator pool = pools.cbegin();
-             pool != pools.cend(); ++pool) {
-            // Prepare the map for a pool (@todo move this code to pool.cc)
-            ElementPtr pool_map = Element::createMap();
-            // Set pool
-            const IOAddress& first = (*pool)->getFirstAddress();
-            const IOAddress& last = (*pool)->getLastAddress();
-            std::string range = first.toText() + "-" + last.toText();
-            // Try to output a prefix (vs a range)
-            int prefix_len = prefixLengthFromRange(first, last);
-            if (prefix_len >= 0) {
-                std::ostringstream oss;
-                oss << first.toText() << "/" << prefix_len;
-                range = oss.str();
-            }
-            pool_map->set("pool", Element::create(range));
-            // Set user-context
-            ConstElementPtr context = (*pool)->getContext();
-            if (!isNull(context)) {
-                pool_map->set("user-context", context);
-            }
-            // Set pool options
-            ConstCfgOptionPtr opts = (*pool)->getCfgOption();
-            pool_map->set("option-data", opts->toElement());
-            // Push on the pool list
-            pool_list->add(pool_map);
-        }
-        map->set("pools", pool_list);
-        // Set host reservation-mode
-        Subnet::HRMode hrmode = (*subnet)->getHostReservationMode();
-        std::string mode;
-        switch (hrmode) {
-        case Subnet::HR_DISABLED:
-            mode = "disabled";
-            break;
-        case Subnet::HR_OUT_OF_POOL:
-            mode = "out-of-pool";
-            break;
-        case Subnet::HR_ALL:
-            mode = "all";
-            break;
-        default:
-            isc_throw(ToElementError,
-                      "invalid host reservation mode: " << hrmode);
-        }
-        map->set("reservation-mode", Element::create(mode));
-        // Set match-client-id
-        map->set("match-client-id",
-                 Element::create((*subnet)->getMatchClientId()));
-        // Set next-server
-        map->set("next-server",
-                 Element::create((*subnet)->getSiaddr().toText()));
-        // Set DHCP4o6
-        const Cfg4o6& d4o6 = (*subnet)->get4o6();
-        isc::data::merge(map, d4o6.toElement());
-        // Set client-class
-        const ClientClasses& cclasses = (*subnet)->getClientClasses();
-        if (cclasses.size() > 1) {
-            isc_throw(ToElementError, "client-class has too many items: "
-                      << cclasses.size());
-        } else if (!cclasses.empty()) {
-            map->set("client-class", Element::create(*cclasses.cbegin()));
-        }
-        // Set options
-        ConstCfgOptionPtr opts = (*subnet)->getCfgOption();
-        map->set("option-data", opts->toElement());
-        // Not supported: interface-id
-        // Not supported: rapid-commit
-        // Push on the list
-        result->add(map);
+        result->add((*subnet)->toElement());
     }
     return (result);
 }

+ 36 - 0
src/lib/dhcpsrv/cfg_subnets4.h

@@ -10,8 +10,10 @@
 #include <asiolink/io_address.h>
 #include <cc/cfg_to_element.h>
 #include <dhcpsrv/subnet.h>
+#include <dhcpsrv/subnet_id.h>
 #include <dhcpsrv/subnet_selector.h>
 #include <boost/shared_ptr.hpp>
+#include <string>
 
 namespace isc {
 namespace dhcp {
@@ -48,6 +50,40 @@ public:
         return (&subnets_);
     }
 
+    /// @brief Returns const pointer to a subnet identified by the specified
+    /// subnet identifier.
+    ///
+    /// The const pointer is returned by this method to prevent a caller from
+    /// modifying the subnet configuration. Modifications to subnet configuration
+    /// is dangerous and must be done carefully. The subnets' configruation is
+    /// held in the multi index container and any modifications to the subnet
+    /// id or subnet prefix must trigger re-indexing of multi index container.
+    /// There is no possibility to enforce this when the non-const pointer is
+    /// returned.
+    ///
+    /// @param subnet_id Subnet identifier.
+    ///
+    /// @return Pointer to the @c Subnet4 object or null pointer if such
+    /// subnet doesn't exist.
+    ConstSubnet4Ptr getBySubnetId(const SubnetID& subnet_id) const;
+
+    /// @brief Returns const pointer to a subnet which matches the specified
+    /// prefix in the canonical form.
+    ///
+    /// The const pointer is returned by this method to prevent a caller from
+    /// modifying the subnet configuration. Modifications to subnet configuration
+    /// is dangerous and must be done carefully. The subnets' configruation is
+    /// held in the multi index container and any modifications to the subnet
+    /// id or subnet prefix must trigger re-indexing of multi index container.
+    /// There is no possibility to enforce this when the non-const pointer is
+    /// returned.
+    ///
+    /// @param subnet_prefix Subnet prefix, e.g. 10.2.3.0/24
+    ///
+    /// @return Pointer to the @c Subnet4 object or null pointer if such
+    /// subnet doesn't exist.
+    ConstSubnet4Ptr getByPrefix(const std::string& subnet_prefix) const;
+
     /// @brief Returns a pointer to the selected subnet.
     ///
     /// This method tries to retrieve the subnet for the client using various

+ 15 - 165
src/lib/dhcpsrv/cfg_subnets6.cc

@@ -33,6 +33,20 @@ CfgSubnets6::add(const Subnet6Ptr& subnet) {
     subnets_.push_back(subnet);
 }
 
+ConstSubnet6Ptr
+CfgSubnets6::getBySubnetId(const SubnetID& subnet_id) const {
+    const auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
+    auto subnet_it = index.find(subnet_id);
+    return ((subnet_it != index.cend()) ? (*subnet_it) : ConstSubnet6Ptr());
+}
+
+ConstSubnet6Ptr
+CfgSubnets6::getByPrefix(const std::string& subnet_text) const {
+    const auto& index = subnets_.get<SubnetPrefixIndexTag>();
+    auto subnet_it = index.find(subnet_text);
+    return ((subnet_it != index.cend()) ? (*subnet_it) : ConstSubnet6Ptr());
+}
+
 Subnet6Ptr
 CfgSubnets6::selectSubnet(const SubnetSelector& selector) const {
     Subnet6Ptr subnet;
@@ -254,171 +268,7 @@ CfgSubnets6::toElement() const {
     // Iterate subnets
     for (Subnet6Collection::const_iterator subnet = subnets_.cbegin();
          subnet != subnets_.cend(); ++subnet) {
-        // Prepare the map
-        ElementPtr map = Element::createMap();
-        // Set subnet id
-        SubnetID id = (*subnet)->getID();
-        map->set("id", Element::create(static_cast<long long>(id)));
-        // Set relay info
-        const Subnet::RelayInfo& relay_info = (*subnet)->getRelayInfo();
-        ElementPtr relay = Element::createMap();
-        relay->set("ip-address", Element::create(relay_info.addr_.toText()));
-        map->set("relay", relay);
-        // Set subnet
-        map->set("subnet", Element::create((*subnet)->toText()));
-        // Set interface
-        const std::string& iface = (*subnet)->getIface();
-        map->set("interface", Element::create(iface));
-        // Set interface-id
-        const OptionPtr& ifaceid = (*subnet)->getInterfaceId();
-        if (ifaceid) {
-            std::vector<uint8_t> bin = ifaceid->getData();
-            std::string ifid;
-            ifid.resize(bin.size());
-            if (!bin.empty()) {
-                std::memcpy(&ifid[0], &bin[0], bin.size());
-            }
-            map->set("interface-id", Element::create(ifid));
-        } else {
-            map->set("interface-id", Element::create(std::string()));
-        }
-        // Set renew-timer
-        map->set("renew-timer",
-                 Element::create(static_cast<long long>
-                                 ((*subnet)->getT1().get())));
-        // Set rebind-timer
-        map->set("rebind-timer",
-                 Element::create(static_cast<long long>
-                                 ((*subnet)->getT2().get())));
-        // Set preferred-lifetime
-        map->set("preferred-lifetime",
-                 Element::create(static_cast<long long>
-                                 ((*subnet)->getPreferred().get())));
-        // Set valid-lifetime
-        map->set("valid-lifetime",
-                 Element::create(static_cast<long long>
-                                 ((*subnet)->getValid().get())));
-        // Set rapid-commit
-        bool rapid_commit = (*subnet)->getRapidCommit();
-        map->set("rapid-commit", Element::create(rapid_commit));
-        // Set pools
-        const PoolCollection& pools = (*subnet)->getPools(Lease::TYPE_NA);
-        ElementPtr pool_list = Element::createList();
-        for (PoolCollection::const_iterator pool = pools.cbegin();
-             pool != pools.cend(); ++pool) {
-            // Prepare the map for a pool (@todo move this code to pool.cc)
-            ElementPtr pool_map = Element::createMap();
-            // Set pool
-            const IOAddress& first = (*pool)->getFirstAddress();
-            const IOAddress& last = (*pool)->getLastAddress();
-            std::string range = first.toText() + "-" + last.toText();
-            // Try to output a prefix (vs a range)
-            int prefix_len = prefixLengthFromRange(first, last);
-            if (prefix_len >= 0) {
-                std::ostringstream oss;
-                oss << first.toText() << "/" << prefix_len;
-                range = oss.str();
-            }
-            pool_map->set("pool", Element::create(range));
-            // Set user-context
-            ConstElementPtr context = (*pool)->getContext();
-            if (!isNull(context)) {
-                pool_map->set("user-context", context);
-            }
-            // Set pool options
-            ConstCfgOptionPtr opts = (*pool)->getCfgOption();
-            pool_map->set("option-data", opts->toElement());
-            // Push on the pool list
-            pool_list->add(pool_map);
-        }
-        map->set("pools", pool_list);
-        // Set pd-pools
-        const PoolCollection& pdpools = (*subnet)->getPools(Lease::TYPE_PD);
-        ElementPtr pdpool_list = Element::createList();
-        for (PoolCollection::const_iterator pool = pdpools.cbegin();
-             pool != pdpools.cend(); ++pool) {
-            // Get it as a Pool6 (@todo move this code to pool.cc)
-            const Pool6* pdpool = dynamic_cast<Pool6*>(pool->get());
-            if (!pdpool) {
-                isc_throw(ToElementError, "invalid pd-pool pointer");
-            }
-            // Prepare the map for a pd-pool
-            ElementPtr pool_map = Element::createMap();
-            // Set prefix
-            const IOAddress& prefix = pdpool->getFirstAddress();
-            pool_map->set("prefix", Element::create(prefix.toText()));
-            // Set prefix-len (get it from min - max)
-            const IOAddress& last = pdpool->getLastAddress();
-            int prefix_len = prefixLengthFromRange(prefix, last);
-            if (prefix_len < 0) {
-                // The pool is bad: give up
-                isc_throw(ToElementError, "invalid prefix range "
-                          << prefix.toText() << "-" << last.toText());
-            }
-            pool_map->set("prefix-len", Element::create(prefix_len));
-            // Set delegated-len
-            uint8_t len = pdpool->getLength();
-            pool_map->set("delegated-len",
-                          Element::create(static_cast<int>(len)));
-            // Set excluded prefix
-            const Option6PDExcludePtr& xopt =
-                pdpool->getPrefixExcludeOption();
-            if (xopt) {
-                const IOAddress& xprefix =
-                    xopt->getExcludedPrefix(prefix, len);
-                pool_map->set("excluded-prefix",
-                              Element::create(xprefix.toText()));
-                uint8_t xlen = xopt->getExcludedPrefixLength();
-                pool_map->set("excluded-prefix-len",
-                              Element::create(static_cast<int>(xlen)));
-            } else {
-                pool_map->set("excluded-prefix",
-                              Element::create(std::string("::")));
-                pool_map->set("excluded-prefix-len", Element::create(0));
-            }
-            // Set user-context
-            ConstElementPtr context = pdpool->getContext();
-            if (!isNull(context)) {
-                pool_map->set("user-context", context);
-            }
-            // Set pool options
-            ConstCfgOptionPtr opts = pdpool->getCfgOption();
-            pool_map->set("option-data", opts->toElement());
-            // Push on the pool list
-            pdpool_list->add(pool_map);
-        }
-        map->set("pd-pools", pdpool_list);
-        // Set host reservation-mode
-        Subnet::HRMode hrmode = (*subnet)->getHostReservationMode();
-        std::string mode;
-        switch (hrmode) {
-        case Subnet::HR_DISABLED:
-            mode = "disabled";
-            break;
-        case Subnet::HR_OUT_OF_POOL:
-            mode = "out-of-pool";
-            break;
-        case Subnet::HR_ALL:
-            mode = "all";
-            break;
-        default:
-            isc_throw(ToElementError,
-                      "invalid host reservation mode: " << hrmode);
-        }
-        map->set("reservation-mode", Element::create(mode));
-        // Set client-class
-        const ClientClasses& cclasses = (*subnet)->getClientClasses();
-        if (cclasses.size() > 1) {
-            isc_throw(ToElementError, "client-class has too many items: "
-                      << cclasses.size());
-        } else if (!cclasses.empty()) {
-            map->set("client-class", Element::create(*cclasses.cbegin()));
-        }
-        // Set options
-        ConstCfgOptionPtr opts = (*subnet)->getCfgOption();
-        map->set("option-data", opts->toElement());
-        // Push on the list
-        result->add(map);
+        result->add((*subnet)->toElement());
     }
     return (result);
 }

+ 37 - 1
src/lib/dhcpsrv/cfg_subnets6.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2015,2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -11,9 +11,11 @@
 #include <dhcp/option.h>
 #include <cc/cfg_to_element.h>
 #include <dhcpsrv/subnet.h>
+#include <dhcpsrv/subnet_id.h>
 #include <dhcpsrv/subnet_selector.h>
 #include <util/optional_value.h>
 #include <boost/shared_ptr.hpp>
+#include <string>
 
 namespace isc {
 namespace dhcp {
@@ -49,6 +51,40 @@ public:
         return (&subnets_);
     }
 
+    /// @brief Returns const pointer to a subnet identified by the specified
+    /// subnet identifier.
+    ///
+    /// The const pointer is returned by this method to prevent a caller from
+    /// modifying the subnet configuration. Modifications to subnet configuration
+    /// is dangerous and must be done carefully. The subnets' configuration is
+    /// held in the multi index container and any modifications to the subnet
+    /// id or subnet prefix must trigger re-indexing of multi index container.
+    /// There is no possibility to enforce this when the non-const pointer is
+    /// returned.
+    ///
+    /// @param subnet_id Subnet identifier.
+    ///
+    /// @return Pointer to the @c Subnet6 object or null pointer if such
+    /// subnet doesn't exist.
+    ConstSubnet6Ptr getBySubnetId(const SubnetID& subnet_id) const;
+
+    /// @brief Returns const pointer to a subnet which matches the specified
+    /// prefix in the canonical form.
+    ///
+    /// The const pointer is returned by this method to prevent a caller from
+    /// modifying the subnet configuration. Modifications to subnet configuration
+    /// is dangerous and must be done carefully. The subnets' configruation is
+    /// held in the multi index container and any modifications to the subnet
+    /// id or subnet prefix must trigger re-indexing of multi index container.
+    /// There is no possibility to enforce this when the non-const pointer is
+    /// returned.
+    ///
+    /// @param subnet_prefix Subnet prefix, e.g. 2001:db8:1::/64
+    ///
+    /// @return Pointer to the @c Subnet6 object or null pointer if such
+    /// subnet doesn't exist.
+    ConstSubnet6Ptr getByPrefix(const std::string& subnet_prefix) const;
+
     /// @brief Selects a subnet using parameters specified in the selector.
     ///
     /// This method tries to retrieve the subnet for the client using various

+ 107 - 0
src/lib/dhcpsrv/pool.cc

@@ -10,6 +10,7 @@
 #include <sstream>
 
 using namespace isc::asiolink;
+using namespace isc::data;
 
 namespace isc {
 namespace dhcp {
@@ -74,6 +75,46 @@ Pool4::Pool4( const isc::asiolink::IOAddress& prefix, uint8_t prefix_len)
     capacity_ = addrsInRange(prefix, last_);
 }
 
+data::ElementPtr
+Pool::toElement() const {
+    // Prepare the map
+    ElementPtr map = Element::createMap();
+
+    // Set user-context
+    ConstElementPtr context = getContext();
+    if (!isNull(context)) {
+        map->set("user-context", context);
+    }
+
+    // Set pool options
+    ConstCfgOptionPtr opts = getCfgOption();
+    map->set("option-data", opts->toElement());
+    return (map);
+}
+
+data::ElementPtr
+Pool4::toElement() const {
+    // Prepare the map
+    ElementPtr map = Pool::toElement();
+
+    // Set pool
+    const IOAddress& first = getFirstAddress();
+    const IOAddress& last = getLastAddress();
+    std::string range = first.toText() + "-" + last.toText();
+
+    // Try to output a prefix (vs a range)
+    int prefix_len = prefixLengthFromRange(first, last);
+    if (prefix_len >= 0) {
+        std::ostringstream oss;
+        oss << first.toText() << "/" << prefix_len;
+        range = oss.str();
+    }
+
+    map->set("pool", Element::create(range));
+    return (map);
+}
+
+
 Pool6::Pool6(Lease::Type type, const isc::asiolink::IOAddress& first,
              const isc::asiolink::IOAddress& last)
     : Pool(type, first, last), prefix_len_(128), pd_exclude_option_() {
@@ -235,6 +276,72 @@ Pool6::init(const Lease::Type& type,
     }
 }
 
+data::ElementPtr
+Pool6::toElement() const {
+    // Prepare the map
+    ElementPtr map = Pool::toElement();
+
+    switch (getType()) {
+        case Lease::TYPE_NA: {
+            const IOAddress& first = getFirstAddress();
+            const IOAddress& last = getLastAddress();
+            std::string range = first.toText() + "-" + last.toText();
+
+            // Try to output a prefix (vs a range)
+            int prefix_len = prefixLengthFromRange(first, last);
+            if (prefix_len >= 0) {
+                std::ostringstream oss;
+                oss << first.toText() << "/" << prefix_len;
+                range = oss.str();
+            }
+
+            map->set("pool", Element::create(range));
+            break;
+        }
+        case Lease::TYPE_PD: {
+            // Set prefix
+            const IOAddress& prefix = getFirstAddress();
+            map->set("prefix", Element::create(prefix.toText()));
+
+            // Set prefix-len (get it from min - max)
+            const IOAddress& last = getLastAddress();
+            int prefix_len = prefixLengthFromRange(prefix, last);
+            if (prefix_len < 0) {
+                // The pool is bad: give up
+                isc_throw(ToElementError, "invalid prefix range "
+                          << prefix.toText() << "-" << last.toText());
+            }
+
+            // Set delegated-len
+            uint8_t len = getLength();
+            map->set("delegated-len", Element::create(static_cast<int>(len)));
+
+            // Set excluded prefix
+            const Option6PDExcludePtr& xopt = getPrefixExcludeOption();
+            if (xopt) {
+                const IOAddress& xprefix = xopt->getExcludedPrefix(prefix, len);
+                map->set("excluded-prefix", Element::create(xprefix.toText()));
+
+                uint8_t xlen = xopt->getExcludedPrefixLength();
+                map->set("excluded-prefix-len",
+                         Element::create(static_cast<int>(xlen)));
+            } else {
+                map->set("excluded-prefix", Element::create(std::string("::")));
+                map->set("excluded-prefix-len", Element::create(0));
+            }
+
+            break;
+        }
+        default:
+            isc_throw(ToElementError, "Lease type: " << getType()
+                      << ", unsupported for Pool6");
+            break;
+    }
+
+    return (map);
+}
+
+
 std::string
 Pool6::toText() const {
     std::ostringstream s;

+ 15 - 0
src/lib/dhcpsrv/pool.h

@@ -106,6 +106,11 @@ public:
         user_context_ = ctx;
     }
 
+    /// @brief Unparse a pool object.
+    ///
+    /// @return A pointer to unparsed pool configuration.
+    virtual data::ElementPtr toElement() const;
+
 protected:
 
     /// @brief protected constructor
@@ -182,6 +187,11 @@ public:
     /// @param prefix_len specifies length of the prefix of the pool
     Pool4(const isc::asiolink::IOAddress& prefix,
           uint8_t prefix_len);
+
+    /// @brief Unparse a Pool4 object.
+    ///
+    /// @return A pointer to unparsed Pool4 configuration.
+    virtual data::ElementPtr toElement() const;
 };
 
 /// @brief a pointer an IPv4 Pool
@@ -275,6 +285,11 @@ public:
         return (pd_exclude_option_);
     }
 
+    /// @brief Unparse a Pool6 object.
+    ///
+    /// @return A pointer to unparsed Pool6 configuration.
+    virtual data::ElementPtr toElement() const;
+
     /// @brief returns textual representation of the pool
     ///
     /// @return textual representation

+ 216 - 0
src/lib/dhcpsrv/subnet.cc

@@ -14,6 +14,7 @@
 #include <sstream>
 
 using namespace isc::asiolink;
+using namespace isc::data;
 using namespace isc::dhcp;
 
 namespace {
@@ -472,5 +473,220 @@ void Subnet6::checkType(Lease::Type type) const {
     }
 }
 
+data::ElementPtr
+Subnet::toElement() const {
+    // Prepare the map
+    ElementPtr map = Element::createMap();
+
+    // Set subnet id
+    SubnetID id = getID();
+    map->set("id", Element::create(static_cast<long long>(id)));
+
+    // Set relay info
+    const Subnet::RelayInfo& relay_info = getRelayInfo();
+    ElementPtr relay = Element::createMap();
+    relay->set("ip-address", Element::create(relay_info.addr_.toText()));
+    map->set("relay", relay);
+
+    // Set subnet
+    map->set("subnet", Element::create(toText()));
+
+    // Set interface
+    const std::string& iface = getIface();
+    if (!iface.empty()) {
+        map->set("interface", Element::create(iface));
+    }
+
+    // Set renew-timer
+    map->set("renew-timer",
+             Element::create(static_cast<long long>
+                                 (getT1().get())));
+    // Set rebind-timer
+    map->set("rebind-timer",
+             Element::create(static_cast<long long>
+                                 (getT2().get())));
+    // Set valid-lifetime
+    map->set("valid-lifetime",
+             Element::create(static_cast<long long>
+                                 (getValid().get())));
+
+    // Set reservation mode
+    Subnet::HRMode hrmode = getHostReservationMode();
+    std::string mode;
+    switch (hrmode) {
+    case Subnet::HR_DISABLED:
+        mode = "disabled";
+        break;
+    case Subnet::HR_OUT_OF_POOL:
+        mode = "out-of-pool";
+        break;
+    case Subnet::HR_ALL:
+        mode = "all";
+        break;
+    default:
+        isc_throw(ToElementError,
+                  "invalid host reservation mode: " << hrmode);
+    }
+    map->set("reservation-mode", Element::create(mode));
+
+    // Set client-class
+    const ClientClasses& cclasses = getClientClasses();
+    if (cclasses.size() > 1) {
+        isc_throw(ToElementError, "client-class has too many items: "
+                  << cclasses.size());
+    } else if (!cclasses.empty()) {
+        map->set("client-class", Element::create(*cclasses.cbegin()));
+    }
+
+    // Set options
+    ConstCfgOptionPtr opts = getCfgOption();
+    map->set("option-data", opts->toElement());
+
+    return (map);
+}
+
+data::ElementPtr
+Subnet4::toElement() const {
+    // Prepare the map
+    ElementPtr map = Subnet::toElement();
+
+    // Set match-client-id
+    map->set("match-client-id", Element::create(getMatchClientId()));
+
+    // Set DHCP4o6
+    const Cfg4o6& d4o6 = get4o6();
+    isc::data::merge(map, d4o6.toElement());
+
+    // Set next-server
+    map->set("next-server", Element::create(getSiaddr().toText()));
+
+    // Set pools
+    const PoolCollection& pools = getPools(Lease::TYPE_V4);
+    ElementPtr pool_list = Element::createList();
+    for (PoolCollection::const_iterator pool = pools.cbegin();
+         pool != pools.cend(); ++pool) {
+        // Add the elementized pool to the list
+        pool_list->add((*pool)->toElement());
+    }
+    map->set("pools", pool_list);
+
+    return (map);
+}
+
+data::ElementPtr
+Subnet6::toElement() const {
+    // Prepare the map
+    ElementPtr map = Subnet::toElement();
+
+    // Set interface-id
+    const OptionPtr& ifaceid = getInterfaceId();
+    if (ifaceid) {
+        std::vector<uint8_t> bin = ifaceid->getData();
+        std::string ifid;
+        ifid.resize(bin.size());
+        if (!bin.empty()) {
+            std::memcpy(&ifid[0], &bin[0], bin.size());
+        }
+        map->set("interface-id", Element::create(ifid));
+    } 
+
+    // Set preferred-lifetime
+    map->set("preferred-lifetime",
+             Element::create(static_cast<long long>
+                             (getPreferred().get())));
+    // Set rapid-commit
+    bool rapid_commit = getRapidCommit();
+    map->set("rapid-commit", Element::create(rapid_commit));
+
+    // Set pools
+    const PoolCollection& pools = getPools(Lease::TYPE_NA);
+    ElementPtr pool_list = Element::createList();
+    for (PoolCollection::const_iterator pool = pools.cbegin();
+         pool != pools.cend(); ++pool) {
+        // Prepare the map for a pool (@todo move this code to pool.cc)
+        ElementPtr pool_map = Element::createMap();
+        // Set pool
+        const IOAddress& first = (*pool)->getFirstAddress();
+        const IOAddress& last = (*pool)->getLastAddress();
+        std::string range = first.toText() + "-" + last.toText();
+        // Try to output a prefix (vs a range)
+        int prefix_len = prefixLengthFromRange(first, last);
+        if (prefix_len >= 0) {
+            std::ostringstream oss;
+            oss << first.toText() << "/" << prefix_len;
+            range = oss.str();
+        }
+        pool_map->set("pool", Element::create(range));
+        // Set user-context
+        ConstElementPtr context = (*pool)->getContext();
+        if (!isNull(context)) {
+            pool_map->set("user-context", context);
+        }
+        // Set pool options
+        ConstCfgOptionPtr opts = (*pool)->getCfgOption();
+        pool_map->set("option-data", opts->toElement());
+        // Push on the pool list
+        pool_list->add(pool_map);
+    }
+    map->set("pools", pool_list);
+    // Set pd-pools
+    const PoolCollection& pdpools = getPools(Lease::TYPE_PD);
+    ElementPtr pdpool_list = Element::createList();
+    for (PoolCollection::const_iterator pool = pdpools.cbegin();
+         pool != pdpools.cend(); ++pool) {
+        // Get it as a Pool6 (@todo move this code to pool.cc)
+        const Pool6* pdpool = dynamic_cast<Pool6*>(pool->get());
+        if (!pdpool) {
+            isc_throw(ToElementError, "invalid pd-pool pointer");
+        }
+        // Prepare the map for a pd-pool
+        ElementPtr pool_map = Element::createMap();
+        // Set prefix
+        const IOAddress& prefix = pdpool->getFirstAddress();
+        pool_map->set("prefix", Element::create(prefix.toText()));
+        // Set prefix-len (get it from min - max)
+        const IOAddress& last = pdpool->getLastAddress();
+        int prefix_len = prefixLengthFromRange(prefix, last);
+        if (prefix_len < 0) {
+            // The pool is bad: give up
+            isc_throw(ToElementError, "invalid prefix range "
+                      << prefix.toText() << "-" << last.toText());
+        }
+        pool_map->set("prefix-len", Element::create(prefix_len));
+        // Set delegated-len
+        uint8_t len = pdpool->getLength();
+        pool_map->set("delegated-len",
+                      Element::create(static_cast<int>(len)));
+
+        // Set excluded prefix
+        const Option6PDExcludePtr& xopt =
+            pdpool->getPrefixExcludeOption();
+        if (xopt) {
+            const IOAddress& xprefix =
+                xopt->getExcludedPrefix(prefix, len);
+            pool_map->set("excluded-prefix",
+                          Element::create(xprefix.toText()));
+            uint8_t xlen = xopt->getExcludedPrefixLength();
+            pool_map->set("excluded-prefix-len",
+                          Element::create(static_cast<int>(xlen)));
+        }
+
+        // Set user-context
+        ConstElementPtr context = pdpool->getContext();
+        if (!isNull(context)) {
+            pool_map->set("user-context", context);
+        }
+        // Set pool options
+        ConstCfgOptionPtr opts = pdpool->getCfgOption();
+        pool_map->set("option-data", opts->toElement());
+        // Push on the pool list
+        pdpool_list->add(pool_map);
+    }
+    map->set("pd-pools", pdpool_list);
+
+    return (map);
+}
+
+
 } // end of isc::dhcp namespace
 } // end of isc namespace

+ 108 - 11
src/lib/dhcpsrv/subnet.h

@@ -8,6 +8,7 @@
 #define SUBNET_H
 
 #include <asiolink/io_address.h>
+#include <cc/data.h>
 #include <dhcp/option.h>
 #include <dhcp/classify.h>
 #include <dhcp/option_space_container.h>
@@ -18,6 +19,11 @@
 #include <dhcpsrv/subnet_id.h>
 #include <dhcpsrv/triplet.h>
 
+#include <boost/multi_index/mem_fun.hpp>
+#include <boost/multi_index/indexed_by.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/random_access_index.hpp>
+#include <boost/multi_index_container.hpp>
 #include <boost/shared_ptr.hpp>
 
 namespace isc {
@@ -280,7 +286,7 @@ public:
     /// returned it is valid.
     ///
     /// @return const reference to the relay information
-    const isc::dhcp::Subnet::RelayInfo& getRelayInfo() {
+    const isc::dhcp::Subnet::RelayInfo& getRelayInfo() const {
         return (relay_);
     }
 
@@ -429,6 +435,11 @@ protected:
     /// type.
     bool poolOverlaps(const Lease::Type& pool_type, const PoolPtr& pool) const;
 
+    /// @brief Unparse a subnet object.
+    ///
+    /// @return A pointer to unparsed subnet configuration.
+    virtual data::ElementPtr toElement() const;
+
     /// @brief subnet-id
     ///
     /// Subnet-id is a unique value that can be used to find or identify
@@ -577,6 +588,19 @@ public:
         return (dhcp4o6_);
     }
 
+    /// @brief Returns const DHCP4o6 configuration parameters.
+    ///
+    /// This structure is always available. If the 4o6 is not enabled, its
+    /// enabled_ field will be set to false.
+    const Cfg4o6& get4o6() const {
+        return (dhcp4o6_);
+    }
+
+    /// @brief Unparse a subnet object.
+    ///
+    /// @return A pointer to unparsed subnet configuration.
+    virtual data::ElementPtr toElement() const;
+
 private:
 
     /// @brief Returns default address for pool selection
@@ -604,16 +628,12 @@ private:
     Cfg4o6 dhcp4o6_;
 };
 
-/// @brief A pointer to a @c Subnet4 object
+/// @brief A const pointer to a @c Subnet4 object.
+typedef boost::shared_ptr<const Subnet4> ConstSubnet4Ptr;
+
+/// @brief A pointer to a @c Subnet4 object.
 typedef boost::shared_ptr<Subnet4> Subnet4Ptr;
 
-/// @brief A collection of @c Subnet4 objects
-///
-/// That is a simple vector of pointers. It does not make much sense to
-/// optimize access time (e.g. using a map), because typical search
-/// pattern will use calling inRange() method on each subnet until
-/// a match is found.
-typedef std::vector<Subnet4Ptr> Subnet4Collection;
 
 /// @brief A configuration holder for IPv6 subnet.
 ///
@@ -676,6 +696,11 @@ public:
         return (rapid_commit_);
     }
 
+    /// @brief Unparse a subnet object.
+    ///
+    /// @return A pointer to unparsed subnet configuration.
+    virtual data::ElementPtr toElement() const;
+
 private:
 
     /// @brief Returns default address for pool selection
@@ -707,11 +732,83 @@ private:
 
 };
 
+/// @brief A const pointer to a @c Subnet6 object.
+typedef boost::shared_ptr<const Subnet6> ConstSubnet6Ptr;
+
 /// @brief A pointer to a Subnet6 object
 typedef boost::shared_ptr<Subnet6> Subnet6Ptr;
 
-/// @brief A collection of Subnet6 objects
-typedef std::vector<Subnet6Ptr> Subnet6Collection;
+/// @name Definition of the multi index container holding subnet information
+///
+//@{
+
+/// @brief Tag for the random access index.
+struct SubnetRandomAccessIndexTag { };
+
+/// @brief Tag for the index for searching by subnet identifier.
+struct SubnetSubnetIdIndexTag { };
+
+/// @brief Tag for the index for searching by subnet prefix.
+struct SubnetPrefixIndexTag { };
+
+/// @brief Multi index container holding subnets.
+///
+/// This multi index container can hold pointers to @ref Subnet4 or
+/// @ref Subnet6 objects representing subnets. It provides indexes for
+/// subnet lookups using subnet properties such as: subnet identifier
+/// or subnet prefix. It also provides a random access index which
+/// allows for using the container like a vector.
+///
+/// The random access index is used by the DHCP servers which perform
+/// a full scan on subnets to find the one that matches some specific
+/// criteria for subnet selection.
+///
+/// The remaining indexes are used for searching for a specific subnet
+/// as a result of receiving a command over the control API, e.g.
+/// when 'subnet-get' command is received.
+///
+/// @todo We should consider optimizing subnet selection by leveraging
+/// the indexing capabilities of this container, e.g. searching for
+/// a subnet by interface name, relay address etc.
+///
+/// @tparam SubnetType Type of the subnet: @ref Subnet4 or @ref Subnet6.
+template<typename SubnetType>
+using SubnetCollection = boost::multi_index_container<
+    // Multi index container holds pointers to the subnets.
+    boost::shared_ptr<SubnetType>,
+    // The following holds all indexes.
+    boost::multi_index::indexed_by<
+        // First is the random access index allowing for accessing
+        // objects just like we'd do with a vector.
+        boost::multi_index::random_access<
+            boost::multi_index::tag<SubnetRandomAccessIndexTag>
+        >,
+        // Second index allows for searching using subnet identifier.
+        boost::multi_index::ordered_unique<
+            boost::multi_index::tag<SubnetSubnetIdIndexTag>,
+            boost::multi_index::const_mem_fun<Subnet, SubnetID, &Subnet::getID>
+        >,
+        // Third index allows for searching using an output from toText function.
+        boost::multi_index::ordered_unique<
+            boost::multi_index::tag<SubnetPrefixIndexTag>,
+            boost::multi_index::const_mem_fun<Subnet, std::string, &Subnet::toText>
+        >
+    >
+>;
+
+/// @brief A collection of @c Subnet4 objects
+///
+/// This container provides a set of indexes which can be used to retrieve
+/// subnets by various properties.
+typedef SubnetCollection<Subnet4> Subnet4Collection;
+
+/// @brief A collection of @c Subnet6 objects
+///
+/// This container provides a set of indexes which can be used to retrieve
+/// subnets by various properties.
+typedef SubnetCollection<Subnet6> Subnet6Collection;
+
+//@}
 
 } // end of isc::dhcp namespace
 } // end of isc namespace

+ 2 - 0
src/lib/dhcpsrv/tests/alloc_engine_utils.cc

@@ -529,6 +529,8 @@ AllocEngine4Test::initSubnet(const asiolink::IOAddress& pool_start,
 
 AllocEngine4Test::AllocEngine4Test() {
 
+    CfgMgr::instance().clear();
+
     // This lease mgr needs to exist to before configuration commits.
     factory_.create("type=memfile universe=4 persist=false");
 

+ 51 - 2
src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc

@@ -23,6 +23,57 @@ using namespace isc::test;
 
 namespace {
 
+// This test verifies that specific subnet can be retrieved by specifying
+// subnet identifier or subnet prefix.
+TEST(CfgSubnets4Test, getSpecificSubnet) {
+    CfgSubnets4 cfg;
+
+    // Create 3 subnets.
+    Subnet4Ptr subnet1(new Subnet4(IOAddress("192.0.2.0"),
+                                   26, 1, 2, 3, SubnetID(5)));
+    Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.2.64"),
+                                   26, 1, 2, 3, SubnetID(8)));
+    Subnet4Ptr subnet3(new Subnet4(IOAddress("192.0.2.128"),
+                                   26, 1, 2, 3, SubnetID(10)));
+
+    // Store the subnets in a vector to make it possible to loop over
+    // all configured subnets.
+    std::vector<Subnet4Ptr> subnets;
+    subnets.push_back(subnet1);
+    subnets.push_back(subnet2);
+    subnets.push_back(subnet3);
+
+    // Add all subnets to the configuration.
+    for (auto subnet = subnets.cbegin(); subnet != subnets.cend(); ++subnet) {
+        ASSERT_NO_THROW(cfg.add(*subnet)) << "failed to add subnet with id: "
+            << (*subnet)->getID();
+    }
+
+    // Iterate over all subnets and make sure they can be retrieved by
+    // subnet identifier.
+    for (auto subnet = subnets.rbegin(); subnet != subnets.rend(); ++subnet) {
+        ConstSubnet4Ptr subnet_returned = cfg.getBySubnetId((*subnet)->getID());
+        ASSERT_TRUE(subnet_returned) << "failed to return subnet with id: "
+            << (*subnet)->getID();
+        EXPECT_EQ((*subnet)->getID(), subnet_returned->getID());
+        EXPECT_EQ((*subnet)->toText(), subnet_returned->toText());
+    }
+
+    // Repeat the previous test, but this time retrieve subnets by their
+    // prefixes.
+    for (auto subnet = subnets.rbegin(); subnet != subnets.rend(); ++subnet) {
+        ConstSubnet4Ptr subnet_returned = cfg.getByPrefix((*subnet)->toText());
+        ASSERT_TRUE(subnet_returned) << "failed to return subnet with id: "
+            << (*subnet)->getID();
+        EXPECT_EQ((*subnet)->getID(), subnet_returned->getID());
+        EXPECT_EQ((*subnet)->toText(), subnet_returned->toText());
+    }
+
+    // Make sure that null pointers are returned for non-existing subnets.
+    EXPECT_FALSE(cfg.getBySubnetId(SubnetID(123)));
+    EXPECT_FALSE(cfg.getByPrefix("10.20.30.0/29"));
+}
+
 // This test verifies that it is possible to retrieve a subnet using an
 // IP address.
 TEST(CfgSubnets4Test, selectSubnetByCiaddr) {
@@ -463,7 +514,6 @@ TEST(CfgSubnets4Test, unparseSubnet) {
         "    \"id\": 123,\n"
         "    \"subnet\": \"192.0.2.0/26\",\n"
         "    \"relay\": { \"ip-address\": \"0.0.0.0\" },\n"
-        "    \"interface\": \"\",\n"
         "    \"match-client-id\": true,\n"
         "    \"next-server\": \"0.0.0.0\",\n"
         "    \"renew-timer\": 1,\n"
@@ -531,7 +581,6 @@ TEST(CfgSubnets4Test, unparsePool) {
         "    \"id\": 123,\n"
         "    \"subnet\": \"192.0.2.0/24\",\n"
         "    \"relay\": { \"ip-address\": \"0.0.0.0\" },\n"
-        "    \"interface\": \"\",\n"
         "    \"match-client-id\": true,\n"
         "    \"next-server\": \"0.0.0.0\",\n"
         "    \"renew-timer\": 1,\n"

+ 51 - 9
src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc

@@ -32,6 +32,57 @@ generateInterfaceId(const std::string& text) {
     return OptionPtr(new Option(Option::V6, D6O_INTERFACE_ID, buffer));
 }
 
+// This test verifies that specific subnet can be retrieved by specifying
+// subnet identifier or subnet prefix.
+TEST(CfgSubnets6Test, getSpecificSubnet) {
+    CfgSubnets6 cfg;
+
+    // Create 3 subnets.
+    Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"), 48, 1, 2, 3, 4,
+                                   SubnetID(5)));
+    Subnet6Ptr subnet2(new Subnet6(IOAddress("2001:db8:2::"), 48, 1, 2, 3, 4,
+                                   SubnetID(8)));
+    Subnet6Ptr subnet3(new Subnet6(IOAddress("2001:db8:3::"), 48, 1, 2, 3, 4,
+                                   SubnetID(10)));
+
+    // Store the subnets in a vector to make it possible to loop over
+    // all configured subnets.
+    std::vector<Subnet6Ptr> subnets;
+    subnets.push_back(subnet1);
+    subnets.push_back(subnet2);
+    subnets.push_back(subnet3);
+
+    // Add all subnets to the configuration.
+    for (auto subnet = subnets.cbegin(); subnet != subnets.cend(); ++subnet) {
+        ASSERT_NO_THROW(cfg.add(*subnet)) << "failed to add subnet with id: "
+            << (*subnet)->getID();
+    }
+
+    // Iterate over all subnets and make sure they can be retrieved by
+    // subnet identifier.
+    for (auto subnet = subnets.rbegin(); subnet != subnets.rend(); ++subnet) {
+        ConstSubnet6Ptr subnet_returned = cfg.getBySubnetId((*subnet)->getID());
+        ASSERT_TRUE(subnet_returned) << "failed to return subnet with id: "
+            << (*subnet)->getID();
+        EXPECT_EQ((*subnet)->getID(), subnet_returned->getID());
+        EXPECT_EQ((*subnet)->toText(), subnet_returned->toText());
+    }
+
+    // Repeat the previous test, but this time retrieve subnets by their
+    // prefixes.
+    for (auto subnet = subnets.rbegin(); subnet != subnets.rend(); ++subnet) {
+        ConstSubnet6Ptr subnet_returned = cfg.getByPrefix((*subnet)->toText());
+        ASSERT_TRUE(subnet_returned) << "failed to return subnet with id: "
+            << (*subnet)->getID();
+        EXPECT_EQ((*subnet)->getID(), subnet_returned->getID());
+        EXPECT_EQ((*subnet)->toText(), subnet_returned->toText());
+    }
+
+    // Make sure that null pointers are returned for non-existing subnets.
+    EXPECT_FALSE(cfg.getBySubnetId(SubnetID(123)));
+    EXPECT_FALSE(cfg.getByPrefix("3000::/16"));
+}
+
 // This test checks that the subnet can be selected using a relay agent's
 // link address.
 TEST(CfgSubnets6Test, selectSubnetByRelayAddress) {
@@ -374,7 +425,6 @@ TEST(CfgSubnets6Test, unparseSubnet) {
         "    \"subnet\": \"2001:db8:1::/48\",\n"
         "    \"relay\": { \"ip-address\": \"::\" },\n"
         "    \"interface-id\": \"relay.eth0\",\n"
-        "    \"interface\": \"\",\n"
         "    \"renew-timer\": 1,\n"
         "    \"rebind-timer\": 2,\n"
         "    \"preferred-lifetime\": 3,\n"
@@ -389,7 +439,6 @@ TEST(CfgSubnets6Test, unparseSubnet) {
         "    \"id\": 124,\n"
         "    \"subnet\": \"2001:db8:2::/48\",\n"
         "    \"relay\": { \"ip-address\": \"2001:db8:ff::2\" },\n"
-        "    \"interface-id\": \"\",\n"
         "    \"interface\": \"lo\",\n"
         "    \"renew-timer\": 1,\n"
         "    \"rebind-timer\": 2,\n"
@@ -404,7 +453,6 @@ TEST(CfgSubnets6Test, unparseSubnet) {
         "    \"id\": 125,\n"
         "    \"subnet\": \"2001:db8:3::/48\",\n"
         "    \"relay\": { \"ip-address\": \"::\" },\n"
-        "    \"interface-id\": \"\",\n"
         "    \"interface\": \"eth1\",\n"
         "    \"renew-timer\": 1,\n"
         "    \"rebind-timer\": 2,\n"
@@ -441,8 +489,6 @@ TEST(CfgSubnets6Test, unparsePool) {
         "    \"id\": 123,\n"
         "    \"subnet\": \"2001:db8:1::/48\",\n"
         "    \"relay\": { \"ip-address\": \"::\" },\n"
-        "    \"interface-id\": \"\",\n"
-        "    \"interface\": \"\",\n"
         "    \"renew-timer\": 1,\n"
         "    \"rebind-timer\": 2,\n"
         "    \"preferred-lifetime\": 3,\n"
@@ -487,8 +533,6 @@ TEST(CfgSubnets6Test, unparsePdPool) {
         "    \"id\": 123,\n"
         "    \"subnet\": \"2001:db8:1::/48\",\n"
         "    \"relay\": { \"ip-address\": \"::\" },\n"
-        "    \"interface-id\": \"\",\n"
-        "    \"interface\": \"\",\n"
         "    \"renew-timer\": 1,\n"
         "    \"rebind-timer\": 2,\n"
         "    \"preferred-lifetime\": 3,\n"
@@ -501,8 +545,6 @@ TEST(CfgSubnets6Test, unparsePdPool) {
         "            \"prefix\": \"2001:db8:2::\",\n"
         "            \"prefix-len\": 48,\n"
         "            \"delegated-len\": 64,\n"
-        "            \"excluded-prefix\": \"::\",\n"
-        "            \"excluded-prefix-len\": 0,\n"
         "            \"option-data\": [ ]\n"
         "        },{\n"
         "            \"prefix\": \"2001:db8:3::\",\n"

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

@@ -51,10 +51,10 @@ public:
             test_subnets4_.push_back(subnet);
         }
         // Create IPv6 subnets.
+        IOAddress prefix("2001:db8:1::");
         for (int i = 0; i < TEST_SUBNETS_NUM; ++i) {
             // This is a base prefix. All other prefixes will be created by
             // modifying this one.
-            IOAddress prefix("2001:db8:1::0");
             std::vector<uint8_t> prefix_bytes = prefix.toBytes();
             // Modify 5th byte of the prefix, so 2001:db8:1::0 becomes
             // 2001:db8:2::0 etc.
@@ -239,7 +239,6 @@ TEST_F(SrvConfigTest, summarySubnets) {
     addSubnet6(1);
     EXPECT_EQ("added IPv4 subnets: 2; added IPv6 subnets: 2",
               conf_.getConfigSummary(SrvConfig::CFGSEL_SUBNET));
-
 }
 
 // Verifies that we can get and set the client class dictionary