Skip to content

Commit 099172d

Browse files
committed
[#3583] Added UTs
/src/bin/dhcp4/tests/classify_unittest.cc TEST_F(ClassifyTest, classTaggingAndAlwaysSend) TEST_F(ClassifyTest, classTaggingAndNeverSend) /src/bin/dhcp6/tests/classify_unittest.cc TEST_F(ClassifyTest, classTaggingAndAlwaysSend) TEST_F(ClassifyTest, classTaggingAndNeverSend)
1 parent d959d41 commit 099172d

File tree

2 files changed

+261
-0
lines changed

2 files changed

+261
-0
lines changed

src/bin/dhcp4/tests/classify_unittest.cc

+134
Original file line numberDiff line numberDiff line change
@@ -2139,4 +2139,138 @@ TEST_F(ClassifyTest, basicOptionClassTagTest) {
21392139
checkServerIdentifier(response1, "0.0.0.0");
21402140
}
21412141

2142+
// Verifies that class-tagging does not subvert always-send.
2143+
TEST_F(ClassifyTest, classTaggingAndAlwaysSend) {
2144+
IfaceMgrTestConfig test_config(true);
2145+
IfaceMgr::instance().openSockets4();
2146+
2147+
NakedDhcpv4Srv srv(0);
2148+
2149+
// Global host-name option disables always-send. Subnet level
2150+
// host-name enables always-send but has a non-matching class
2151+
// tag. The Response should contain the global value for host-name.
2152+
string config = R"^(
2153+
{
2154+
"interfaces-config": {
2155+
"interfaces": [ "*" ]
2156+
},
2157+
"rebind-timer": 2000,
2158+
"renew-timer": 1000,
2159+
"valid-lifetime": 4000,
2160+
"option-data": [{
2161+
"name": "host-name",
2162+
"data": "global.com",
2163+
"always-send" : false,
2164+
"never-send" : false
2165+
}],
2166+
"subnet4": [{
2167+
"id": 1,
2168+
"subnet": "192.0.2.0/24",
2169+
"option-data": [{
2170+
"name": "host-name",
2171+
"data": "subnet.com",
2172+
"client-classes": [ "no-match" ],
2173+
"always-send" : true
2174+
}],
2175+
"pools": [{
2176+
"pool": "192.0.2.1 - 192.0.2.100"
2177+
}]
2178+
}]
2179+
}
2180+
)^";
2181+
2182+
// Configure DHCP server.
2183+
configure(config, srv);
2184+
2185+
// Create a DISCOVER that matches class "melon".
2186+
auto id = ClientId::fromText("31:31:31");
2187+
OptionPtr clientid = (OptionPtr(new Option(Option::V4,
2188+
DHO_DHCP_CLIENT_IDENTIFIER,
2189+
id->getClientId())));
2190+
2191+
Pkt4Ptr query1(new Pkt4(DHCPDISCOVER, 1234));
2192+
query1->setRemoteAddr(IOAddress("192.0.2.1"));
2193+
query1->addOption(clientid);
2194+
query1->setIface("eth1");
2195+
query1->setIndex(ETH1_INDEX);
2196+
2197+
// Configure DHCP server.
2198+
configure(config, srv);
2199+
2200+
// Process query
2201+
Pkt4Ptr response = srv.processDiscover(query1);
2202+
2203+
// Verify that global host-name is present.
2204+
OptionStringPtr hostname;
2205+
hostname = boost::dynamic_pointer_cast<OptionString>(response->getOption(DHO_HOST_NAME));
2206+
ASSERT_TRUE(hostname);
2207+
EXPECT_EQ("global.com", hostname->getValue());
2208+
}
2209+
2210+
// Verifies that class-tagging does not subvert never-send.
2211+
TEST_F(ClassifyTest, classTaggingAndNeverSend) {
2212+
IfaceMgrTestConfig test_config(true);
2213+
IfaceMgr::instance().openSockets4();
2214+
2215+
NakedDhcpv4Srv srv(0);
2216+
2217+
// Global host-name option enables always-send. Subnet level
2218+
// host-name enables never-send but has a non-matching class
2219+
// tag. The Response should not contain a value for host-name.
2220+
string config = R"^(
2221+
{
2222+
"interfaces-config": {
2223+
"interfaces": [ "*" ]
2224+
},
2225+
"rebind-timer": 2000,
2226+
"renew-timer": 1000,
2227+
"valid-lifetime": 4000,
2228+
"option-data": [{
2229+
"name": "host-name",
2230+
"data": "global.com",
2231+
"always-send" : true,
2232+
"never-send" : false
2233+
}],
2234+
"subnet4": [{
2235+
"id": 1,
2236+
"subnet": "192.0.2.0/24",
2237+
"option-data": [{
2238+
"name": "host-name",
2239+
"data": "subnet.com",
2240+
"client-classes": [ "no-match" ],
2241+
"always-send" : false,
2242+
"never-send" : true
2243+
}],
2244+
"pools": [{
2245+
"pool": "192.0.2.1 - 192.0.2.100"
2246+
}]
2247+
}]
2248+
}
2249+
)^";
2250+
2251+
// Configure DHCP server.
2252+
configure(config, srv);
2253+
2254+
// Create a DISCOVER that matches class "melon".
2255+
auto id = ClientId::fromText("31:31:31");
2256+
OptionPtr clientid = (OptionPtr(new Option(Option::V4,
2257+
DHO_DHCP_CLIENT_IDENTIFIER,
2258+
id->getClientId())));
2259+
2260+
Pkt4Ptr query1(new Pkt4(DHCPDISCOVER, 1234));
2261+
query1->setRemoteAddr(IOAddress("192.0.2.1"));
2262+
query1->addOption(clientid);
2263+
query1->setIface("eth1");
2264+
query1->setIndex(ETH1_INDEX);
2265+
2266+
// Configure DHCP server.
2267+
configure(config, srv);
2268+
2269+
// Process query
2270+
Pkt4Ptr response = srv.processDiscover(query1);
2271+
2272+
// The response should not contain host-name.
2273+
ASSERT_FALSE(response->getOption(DHO_HOST_NAME));
2274+
}
2275+
21422276
} // end of anonymous namespace

src/bin/dhcp6/tests/classify_unittest.cc

+127
Original file line numberDiff line numberDiff line change
@@ -3279,4 +3279,131 @@ TEST_F(ClassifyTest, requestedVendorOptionsClassTag) {
32793279
EXPECT_TRUE(custom);
32803280
}
32813281

3282+
// Verifies that class-tagging does not subvert always-send.
3283+
TEST_F(ClassifyTest, classTaggingAndAlwaysSend) {
3284+
IfaceMgrTestConfig test_config(true);
3285+
3286+
NakedDhcpv6Srv srv(0);
3287+
3288+
// Subnet level ipv6-forwarding enables always-send but with a non-matching
3289+
// class-tag. Response should contain the global value for ip6-fowarding.
3290+
std::string config = R"^(
3291+
{
3292+
"interfaces-config": { "interfaces": [ "*" ] },
3293+
"preferred-lifetime": 3000,
3294+
"rebind-timer": 2000,
3295+
"renew-timer": 1000,
3296+
"valid-lifetime": 4000,
3297+
"option-def": [{
3298+
"name": "ipv6-forwarding",
3299+
"code": 2345,
3300+
"type": "boolean"
3301+
}],
3302+
"option-data": [{
3303+
"name": "ipv6-forwarding",
3304+
"data": "true",
3305+
"always-send": false,
3306+
"never-send": false
3307+
}],
3308+
"subnet6": [{
3309+
"pools": [ { "pool": "2001:db8:1::/64" } ],
3310+
"id": 1,
3311+
"subnet": "2001:db8:1::/48",
3312+
"interface": "eth1",
3313+
"option-data": [{
3314+
"name": "ipv6-forwarding",
3315+
"data": "false",
3316+
"client-classes": [ "no-match" ],
3317+
"always-send": true
3318+
3319+
}]
3320+
}]
3321+
}
3322+
)^";
3323+
3324+
ASSERT_NO_THROW(configure(config));
3325+
3326+
// Create a packet with enough to select the subnet and go through
3327+
// the SOLICIT processing
3328+
Pkt6Ptr query = createSolicit();
3329+
3330+
// Do not add an ORO.
3331+
OptionPtr oro = query->getOption(D6O_ORO);
3332+
EXPECT_FALSE(oro);
3333+
3334+
// Process the query
3335+
Pkt6Ptr response;
3336+
processQuery(srv, query, response);
3337+
3338+
// Processing should add the global ip-forwarding option.
3339+
OptionPtr opt = response->getOption(2345);
3340+
ASSERT_TRUE(opt);
3341+
ASSERT_GT(opt->len(), opt->getHeaderLen());
3342+
EXPECT_EQ(1, opt->getUint8());
3343+
}
3344+
3345+
// Verifies that option class-tagging does not subvert never-send.
3346+
TEST_F(ClassifyTest, classTaggingAndNeverSend) {
3347+
IfaceMgrTestConfig test_config(true);
3348+
3349+
NakedDhcpv6Srv srv(0);
3350+
3351+
// Subnet sets an ipv6-forwarding option in the response.
3352+
// The router class matches incoming packets with foo in a host-name
3353+
// option (code 1234) and sets an ipv6-forwarding option in the response.
3354+
// Subnet level option enables never-send non-matching class-tag.
3355+
// Response should not contain a value for ip6-fowarding.
3356+
std::string config = R"^(
3357+
{
3358+
"interfaces-config": { "interfaces": [ "*" ] },
3359+
"preferred-lifetime": 3000,
3360+
"rebind-timer": 2000,
3361+
"renew-timer": 1000,
3362+
"valid-lifetime": 4000,
3363+
"option-def": [{
3364+
"name": "ipv6-forwarding",
3365+
"code": 2345,
3366+
"type": "boolean"
3367+
}],
3368+
"option-data": [{
3369+
"name": "ipv6-forwarding",
3370+
"data": "true",
3371+
"always-send": true,
3372+
"never-send": false
3373+
}],
3374+
"subnet6": [{
3375+
"pools": [ { "pool": "2001:db8:1::/64" } ],
3376+
"id": 1,
3377+
"subnet": "2001:db8:1::/48",
3378+
"interface": "eth1",
3379+
"option-data": [{
3380+
"name": "ipv6-forwarding",
3381+
"data": "false",
3382+
"client-classes": [ "no-match" ],
3383+
"always-send": false,
3384+
"never-send": true
3385+
}]
3386+
}]
3387+
}
3388+
)^";
3389+
3390+
ASSERT_NO_THROW(configure(config));
3391+
3392+
// Create a packet with enough to select the subnet and go through
3393+
// the SOLICIT processing
3394+
Pkt6Ptr query = createSolicit();
3395+
3396+
// Do not add an ORO.
3397+
OptionPtr oro = query->getOption(D6O_ORO);
3398+
EXPECT_FALSE(oro);
3399+
3400+
// Process the query
3401+
Pkt6Ptr response;
3402+
processQuery(srv, query, response);
3403+
3404+
// Processing should not add an ip-forwarding option
3405+
OptionPtr opt = response->getOption(2345);
3406+
ASSERT_FALSE(opt);
3407+
}
3408+
32823409
} // end of anonymous namespace

0 commit comments

Comments
 (0)