Commit dbedf186 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[master] Merge branch 'trac3322' (relay override in client classification)

Conflicts:
	ChangeLog
	src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
parents 431746f9 5de565ba
759. [func] tomek
b10-dhcp4, b10-dhcp6: IP address of the relay agent can now be specified
for both IPv4 and IPv6 subnets. That information allows the server to
properly handle a case where relay agent address does not match subnet.
This is mostly useful in shared subnets and cable networks.
(Trac #3322, git 5de565baea42c9096dff78ed5fbd05982a174469)
758. [bug] tmark
b10-dhcp4 now correctly handles DHO_HOST_OPTION. This corrects a bug
where the server would fail to recognize the option in the DHCP request
......
......@@ -4593,6 +4593,11 @@ Dhcp4/subnet4 [] list (default)
If the message is relayed it is accepted through any interface. The giaddr
set by the relay agent is used to select the subnet for the client.
</para>
<para>
It is also possible to specify a relay IPv4 address for a given subnet. It
can be used to match incoming packets into a subnet in uncommon configurations,
e.g. shared subnets. See <xref linkend="dhcp4-relay-override"/> for details.
</para>
<note>
<para>The subnet selection mechanism described in this section is based
on the assumption that client classification is not used. The classification
......@@ -4601,6 +4606,75 @@ Dhcp4/subnet4 [] list (default)
</note>
</section>
<section id="dhcp4-relay-override">
<title>Using specific relay agent for a subnet</title>
<para>
The relay has to have an interface connected to the link on which
the clients are being configured. Typically the relay has an IPv4
address configured on that interface that belongs to the subnet that
the server will assign addresses from. In such typical case, the
server is able to use IPv4 address inserted by the relay (in GIADDR
field of the DHCPv4 packet) to select appropriate subnet.
</para>
<para>
However, that is not always the case. In certain uncommon, but
valid deployments, the relay address may not match the subnet. This
usually means that there is more than one subnet allocated for a given
link. Two most common examples where this is the case are long lasting
network renumbering (where both old and new address space is still being
used) and a cable network. In a cable network both cable modems and the
devices behind them are physically connected to the same link, yet
they use distinct addressing. In such case, the DHCPv4 server needs
additional information (IPv4 address of the relay) to properly select
an appropriate subnet.
</para>
<para>
The following example assumes that there is a subnet 192.0.2.0/24
that is accessible via relay that uses 10.0.0.1 as its IPv4 address.
The server will be able to select this subnet for any incoming packets
that came from a relay that has an address in 192.0.2.0/24 subnet.
It will also select that subnet for a relay with address 10.0.0.1.
<screen>
&gt; <userinput>config add Dhcp4/subnet4</userinput>
&gt; <userinput>config set Dhcp4/subnet4[0]/subnet "192.0.2.0/24"</userinput>
&gt; <userinput>config set Dhcp4/subnet4[0]/pool [ "192.0.2.10 - 192.0.2.20" ]</userinput>
&gt; <userinput>config set Dhcp4/subnet4[0]/relay/ip-address "10.0.0.1"</userinput>
&gt; <userinput>config commit</userinput></screen>
</para>
</section>
<section id="dhcp4-srv-example-client-class-relay">
<title>Segregating IPv4 clients in a cable network</title>
<para>
In certain cases, it is useful to mix relay address information,
introduced in <xref linkend="dhcp4-relay-override"/> with client
classification, explained in <xref linkend="dhcp4-subnet-class"/>.
One specific example is cable network, where typically modems
get addresses from a different subnet than all devices connected
behind them.
</para>
<para>
Let's assume that there is one CMTS (Cable Modem Termination System)
with one CM MAC (a physical link that modems are connected to).
We want the modems to get addresses from the 10.1.1.0/24 subnet, while
everything connected behind modems should get addresses from another
subnet (192.0.2.0/24). The CMTS that acts as a relay an uses address
10.1.1.1. The following configuration can serve that configuration:
<screen>
&gt; <userinput>config add Dhcp4/subnet4</userinput>
&gt; <userinput>config set Dhcp4/subnet4[0]/subnet "10.1.1.0/24"</userinput>
&gt; <userinput>config set Dhcp4/subnet4[0]/pool [ "10.1.1.2 - 10.1.1.20" ]</userinput>
&gt; <userinput>config set Dhcp4/subnet4[0]/client-class "docsis3.0"</userinput>
&gt; <userinput>config set Dhcp4/subnet4[0]/relay/ip-address "10.1.1.1"</userinput>
&gt; <userinput>config add Dhcp4/subnet4</userinput>
&gt; <userinput>config set Dhcp4/subnet4[1]/subnet "192.0.2.0/24"</userinput>
&gt; <userinput>config set Dhcp4/subnet4[1]/pool [ "192.0.2.10 - 192.0.2.20" ]</userinput>
&gt; <userinput>config set Dhcp4/subnet4[1]/relay/ip-address "10.1.1.1"</userinput>
&gt; <userinput>config commit</userinput></screen>
</para>
</section>
<section id="dhcp4-std">
<title>Supported Standards</title>
<para>The following standards and draft standards are currently
......@@ -4692,6 +4766,23 @@ Dhcp4/renew-timer 1000 integer (default)
</itemizedlist>
</section>
<!--
<section id="dhcp4-srv-examples">
<title>Kea DHCPv4 server examples</title>
<para>
This section provides easy to use example. Each example can be read
separately. It is not intended to be read sequentially as there will
be many repetitions between examples. They are expected to serve as
easy to use copy-paste solutions to many common deployments.
</para>
@todo: add simple configuration for direct clients
@todo: add configuration for relayed clients
@todo: add client classification example
</section> -->
</chapter>
<chapter id="dhcp6">
......@@ -5460,17 +5551,17 @@ should include options from the isc option space:
The DHCPv6 server may receive requests from local (connected to the
same subnet as the server) and remote (connecting via relays) clients.
As server may have many subnet configurations defined, it must select
appropriate subnet for a given request. To do this, the server first
checks if there is only one subnet defined and source of the packet is
link-local. If this is the case, the server assumes that the only
subnet defined is local and client is indeed connected to it. This
check simplifies small deployments.
appropriate subnet for a given request.
</para>
<para>
If there are two or more subnets defined, the server can not assume
which of those (if any) subnets are local. Therefore an optional
"interface" parameter is available within a subnet definition to
designate that a given subnet is local, i.e. reachable directly over
The server can not assume which of configured subnets are local. It is
possible in IPv4, where there is reasonable expectation that the
server will have a (global) IPv4 address configured on the interface,
and can use that information to detect whether a subnet is local or
not. That assumption is not true in IPv6, as the DHCPv6 must be able
to operate with having link-local addresses only. Therefore an optional
&quot;interface&quot; parameter is available within a subnet definition
to designate that a given subnet is local, i.e. reachable directly over
specified interface. For example the server that is intended to serve
a local subnet over eth0 may be configured as follows:
<screen>
......@@ -5643,6 +5734,78 @@ should include options from the isc option space:
</section>
<section id="dhcp6-relay-override">
<title>Using specific relay agent for a subnet</title>
<para>
The relay has to have an interface connected to the link on which
the clients are being configured. Typically the relay has a global IPv6
address configured on that interface that belongs to the subnet that
the server will assign addresses from. In such typical case, the
server is able to use IPv6 address inserted by the relay (in link-addr
field in RELAY-FORW message) to select appropriate subnet.
</para>
<para>
However, that is not always the case. The relay
address may not match the subnet in certain deployments. This
usually means that there is more than one subnet allocated for a given
link. Two most common examples where this is the case are long lasting
network renumbering (where both old and new address space is still being
used) and a cable network. In a cable network both cable modems and the
devices behind them are physically connected to the same link, yet
they use distinct addressing. In such case, the DHCPv6 server needs
additional information (like the value of interface-id option or IPv6
address inserted in the link-addr field in RELAY-FORW message) to
properly select an appropriate subnet.
</para>
<para>
The following example assumes that there is a subnet 2001:db8:1::/64
that is accessible via relay that uses 3000::1 as its IPv6 address.
The server will be able to select this subnet for any incoming packets
that came from a relay that has an address in 2001:db8:1::/64 subnet.
It will also select that subnet for a relay with address 3000::1.
<screen>
&gt; <userinput>config add Dhcp6/subnet6</userinput>
&gt; <userinput>config set Dhcp6/subnet6[0]/subnet "2001:db8:1::/64"</userinput>
&gt; <userinput>config set Dhcp6/subnet6[0]/pool [ "2001:db8:1::2 - 2001:db8:1::ffff" ]</userinput>
&gt; <userinput>config set Dhcp6/subnet6[0]/relay/ip-address "3000::1"</userinput>
&gt; <userinput>config commit</userinput></screen>
</para>
</section>
<section id="dhcp6-client-class-relay">
<title>Segregating IPv6 clients in a cable network</title>
<para>
In certain cases, it is useful to mix relay address information,
introduced in <xref linkend="dhcp6-relay-override"/> with client
classification, explained in <xref linkend="dhcp6-subnet-class"/>.
One specific example is cable network, where typically modems
get addresses from a different subnet than all devices connected
behind them.
</para>
<para>
Let's assume that there is one CMTS (Cable Modem Termination System)
with one CM MAC (a physical link that modems are connected to).
We want the modems to get addresses from the 3000::/64 subnet,
while everything connected behind modems should get addresses from
another subnet (2001:db8:1::/64). The CMTS that acts as a relay
an uses address 3000::1. The following configuration can serve
that configuration:
<screen>
&gt; <userinput>config add Dhcp6/subnet6</userinput>
&gt; <userinput>config set Dhcp6/subnet6[0]/subnet "3000::/64"</userinput>
&gt; <userinput>config set Dhcp6/subnet6[0]/pool [ "3000::2 - 3000::ffff" ]</userinput>
&gt; <userinput>config set Dhcp6/subnet6[0]/client-class "docsis3.0"</userinput>
&gt; <userinput>config set Dhcp6/subnet6[0]/relay/ip-address "3000::1"</userinput>
&gt; <userinput>config add Dhcp6/subnet6</userinput>
&gt; <userinput>config set Dhcp6/subnet6[1]/subnet "2001:db8:1::/64"</userinput>
&gt; <userinput>config set Dhcp6/subnet6[1]/pool [ "2001:db8:1::1 - 2001:db8:1::ffff" ]</userinput>
&gt; <userinput>config set Dhcp6/subnet6[1]/relay/ip-address "3000::1"</userinput>
&gt; <userinput>config commit</userinput></screen>
</para>
</section>
<section id="dhcp6-std">
<title>Supported Standards</title>
<para>The following standards and draft standards are currently
......@@ -5714,6 +5877,23 @@ Dhcp6/renew-timer 1000 integer (default)
</itemizedlist>
</section>
<!--
<section id="dhcp6-srv-examples">
<title>Kea DHCPv6 server examples</title>
<para>
This section provides easy to use example. Each example can be read
separately. It is not intended to be read sequentially as there will
be many repetitions between examples. They are expected to serve as
easy to use copy-paste solutions to many common deployments.
</para>
@todo: add simple configuration for direct clients
@todo: add configuration for relayed clients
@todo: add client classification example
</section> -->
</chapter>
<chapter id="libdhcp">
......
......@@ -1419,7 +1419,8 @@ Dhcpv4Srv::selectSubnet(const Pkt4Ptr& question) const {
// level functions.
if (question->isRelayed()) {
subnet = CfgMgr::instance().getSubnet4(question->getGiaddr(),
question->classes_);
question->classes_,
true);
// The message is not relayed so it is sent directly by a client. But
// the client may be renewing its lease and in such case it unicasts
......
......@@ -3314,10 +3314,6 @@ TEST_F(Dhcpv4SrvTest, clientClassification) {
// .clientClassification above.
TEST_F(Dhcpv4SrvTest, clientClassify2) {
NakedDhcpv4Srv srv(0);
ConstElementPtr status;
// This test configures 2 subnets. We actually only need the
// first one, but since there's still this ugly hack that picks
// the pool if there is only one, we must use more than one
......@@ -3340,15 +3336,9 @@ TEST_F(Dhcpv4SrvTest, clientClassify2) {
"],"
"\"valid-lifetime\": 4000 }";
ElementPtr json = Element::fromJSON(config);
EXPECT_NO_THROW(status = configureDhcp4Server(srv, json));
// check if returned status is OK
ASSERT_TRUE(status);
comment_ = config::parseAnswer(rcode_, status);
ASSERT_EQ(0, rcode_);
ASSERT_NO_THROW(configure(config));
// Create a simple packet that we'll use for classification
Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
dis->setRemoteAddr(IOAddress("192.0.2.1"));
dis->setCiaddr(IOAddress("192.0.2.1"));
......@@ -3358,19 +3348,153 @@ TEST_F(Dhcpv4SrvTest, clientClassify2) {
// This discover does not belong to foo class, so it will not
// be serviced
EXPECT_FALSE(srv.selectSubnet(dis));
EXPECT_FALSE(srv_.selectSubnet(dis));
// Let's add the packet to bar class and try again.
dis->addClass("bar");
// Still not supported, because it belongs to wrong class.
EXPECT_FALSE(srv.selectSubnet(dis));
EXPECT_FALSE(srv_.selectSubnet(dis));
// Let's add it to maching class.
dis->addClass("foo");
// This time it should work
EXPECT_TRUE(srv.selectSubnet(dis));
EXPECT_TRUE(srv_.selectSubnet(dis));
}
// Checks if relay IP address specified in the relay-info structure in
// subnet4 is being used properly.
TEST_F(Dhcpv4SrvTest, relayOverride) {
// We have 2 subnets defined. Note that both have a relay address
// defined. Both are not belonging to the subnets. That is
// important, because if the relay belongs to the subnet, there's
// no need to specify relay override.
string config = "{ \"interfaces\": [ \"*\" ],"
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
"\"subnet4\": [ "
"{ \"pool\": [ \"192.0.2.2 - 192.0.2.100\" ],"
" \"relay\": { "
" \"ip-address\": \"192.0.5.1\""
" },"
" \"subnet\": \"192.0.2.0/24\" }, "
"{ \"pool\": [ \"192.0.3.1 - 192.0.3.100\" ],"
" \"relay\": { "
" \"ip-address\": \"192.0.5.2\""
" },"
" \"subnet\": \"192.0.3.0/24\" } "
"],"
"\"valid-lifetime\": 4000 }";
// Use this config to set up the server
ASSERT_NO_THROW(configure(config));
// Let's get the subnet configuration objects
const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4();
ASSERT_EQ(2, subnets->size());
// Let's get them for easy reference
Subnet4Ptr subnet1 = (*subnets)[0];
Subnet4Ptr subnet2 = (*subnets)[1];
ASSERT_TRUE(subnet1);
ASSERT_TRUE(subnet2);
// Let's create a packet.
Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
dis->setRemoteAddr(IOAddress("192.0.2.1"));
dis->setIface("eth0");
dis->setHops(1);
OptionPtr clientid = generateClientId();
dis->addOption(clientid);
// This is just a sanity check, we're using regular method: ciaddr 192.0.2.1
// belongs to the first subnet, so it is selected
dis->setGiaddr(IOAddress("192.0.2.1"));
EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis));
// Relay belongs to the second subnet, so it should be selected.
dis->setGiaddr(IOAddress("192.0.3.1"));
EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis));
// Now let's check if the relay override for the first subnets works
dis->setGiaddr(IOAddress("192.0.5.1"));
EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis));
// The same check for the second subnet...
dis->setGiaddr(IOAddress("192.0.5.2"));
EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis));
// And finally, let's check if mis-matched relay address will end up
// in not selecting a subnet at all
dis->setGiaddr(IOAddress("192.0.5.3"));
EXPECT_FALSE(srv_.selectSubnet(dis));
// Finally, check that the relay override works only with relay address
// (GIADDR) and does not affect client address (CIADDR)
dis->setGiaddr(IOAddress("0.0.0.0"));
dis->setHops(0);
dis->setCiaddr(IOAddress("192.0.5.1"));
EXPECT_FALSE(srv_.selectSubnet(dis));
}
// Checks if relay IP address specified in the relay-info structure can be
// used together with client-classification.
TEST_F(Dhcpv4SrvTest, relayOverrideAndClientClass) {
// This test configures 2 subnets. They both are on the same link, so they
// have the same relay-ip address. Furthermore, the first subnet is
// reserved for clients that belong to class "foo".
string config = "{ \"interfaces\": [ \"*\" ],"
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
"\"subnet4\": [ "
"{ \"pool\": [ \"192.0.2.2 - 192.0.2.100\" ],"
" \"client-class\": \"foo\", "
" \"relay\": { "
" \"ip-address\": \"192.0.5.1\""
" },"
" \"subnet\": \"192.0.2.0/24\" }, "
"{ \"pool\": [ \"192.0.3.1 - 192.0.3.100\" ],"
" \"relay\": { "
" \"ip-address\": \"192.0.5.1\""
" },"
" \"subnet\": \"192.0.3.0/24\" } "
"],"
"\"valid-lifetime\": 4000 }";
// Use this config to set up the server
ASSERT_NO_THROW(configure(config));
const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4();
ASSERT_EQ(2, subnets->size());
// Let's get them for easy reference
Subnet4Ptr subnet1 = (*subnets)[0];
Subnet4Ptr subnet2 = (*subnets)[1];
ASSERT_TRUE(subnet1);
ASSERT_TRUE(subnet2);
// Let's create a packet.
Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
dis->setRemoteAddr(IOAddress("192.0.2.1"));
dis->setIface("eth0");
dis->setHops(1);
dis->setGiaddr(IOAddress("192.0.5.1"));
OptionPtr clientid = generateClientId();
dis->addOption(clientid);
// This packet does not belong to class foo, so it should be rejected in
// subnet[0], even though the relay-ip matches. It should be accepted in
// subnet[1], because the subnet matches and there are no class
// requirements.
EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis));
// Now let's add this packet to class foo and recheck. This time it should
// be accepted in the first subnet, because both class and relay-ip match.
dis->addClass("foo");
EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis));
}
// This test verifies that the direct message is dropped when it has been
......
......@@ -864,7 +864,7 @@ Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question) {
// if relay filled in link_addr field, then let's use it
if (link_addr != IOAddress("::")) {
subnet = CfgMgr::instance().getSubnet6(link_addr,
question->classes_);
question->classes_, true);
}
}
}
......
......@@ -92,6 +92,7 @@ dhcp6_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/cc/libb10-cc.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/config/libb10-cfgclient.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libb10-dhcp++.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/dhcp/tests/libdhcptest.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/dhcp_ddns/libb10-dhcp_ddns.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/libb10-dhcpsrv.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/hooks/libb10-hooks.la
......
......@@ -29,6 +29,7 @@
#include <dhcp6/config_parser.h>
#include <dhcp/dhcp6.h>
#include <dhcp/docsis3_option_defs.h>
#include <dhcp/tests/iface_mgr_test_config.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/lease_mgr.h>
#include <dhcpsrv/lease_mgr_factory.h>
......@@ -52,6 +53,7 @@ using namespace isc::config;
using namespace isc::test;
using namespace isc::asiolink;
using namespace isc::dhcp;
using namespace isc::dhcp::test;
using namespace isc::util;
using namespace isc::hooks;
using namespace std;
......@@ -283,6 +285,9 @@ TEST_F(Dhcpv6SrvTest, DUID) {
// This test checks if Option Request Option (ORO) is parsed correctly
// and the requested options are actually assigned.
TEST_F(Dhcpv6SrvTest, advertiseOptions) {
IfaceMgrTestConfig test_config(true);
ConstElementPtr x;
string config = "{ \"interfaces\": [ \"all\" ],"
"\"preferred-lifetime\": 3000,"
......@@ -291,6 +296,7 @@ TEST_F(Dhcpv6SrvTest, advertiseOptions) {
"\"subnet6\": [ { "
" \"pool\": [ \"2001:db8:1::/64\" ],"
" \"subnet\": \"2001:db8:1::/48\", "
" \"interface\": \"eth0\", "
" \"option-data\": [ {"
" \"name\": \"dns-servers\","
" \"space\": \"dhcp6\","
......@@ -307,25 +313,17 @@ TEST_F(Dhcpv6SrvTest, advertiseOptions) {
" } ]"
" } ],"
"\"valid-lifetime\": 4000 }";
ElementPtr json = Element::fromJSON(config);
NakedDhcpv6Srv srv(0);
EXPECT_NO_THROW(x = configureDhcp6Server(srv, json));
ASSERT_TRUE(x);
comment_ = parseAnswer(rcode_, x);
ASSERT_EQ(0, rcode_);
ASSERT_NO_THROW(configure(config));
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
sol->setRemoteAddr(IOAddress("fe80::abcd"));
sol->setIface("eth0");
sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
OptionPtr clientid = generateClientId();
sol->addOption(clientid);
// Pass it to the server and get an advertise
Pkt6Ptr adv = srv.processSolicit(sol);
Pkt6Ptr adv = srv_.processSolicit(sol);
// check if we get response at all
ASSERT_TRUE(adv);
......@@ -349,7 +347,7 @@ TEST_F(Dhcpv6SrvTest, advertiseOptions) {
sol->addOption(option_oro);
// Need to process SOLICIT again after requesting new option.
adv = srv.processSolicit(sol);
adv = srv_.processSolicit(sol);
ASSERT_TRUE(adv);
OptionPtr tmp = adv->getOption(D6O_NAME_SERVERS);
......@@ -404,6 +402,7 @@ TEST_F(Dhcpv6SrvTest, SolicitBasic) {
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
sol->setRemoteAddr(IOAddress("fe80::abcd"));
sol->setIface("eth0");
sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
OptionPtr clientid = generateClientId();
sol->addOption(clientid);
......@@ -447,6 +446,7 @@ TEST_F(Dhcpv6SrvTest, pdSolicitBasic) {
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
sol->setRemoteAddr(IOAddress("fe80::abcd"));
sol->setIface("eth0");
sol->addOption(generateIA(D6O_IA_PD, 234, 1500, 3000));
OptionPtr clientid = generateClientId();
sol->addOption(clientid);
......@@ -492,6 +492,7 @@ TEST_F(Dhcpv6SrvTest, SolicitHint) {
// Let's create a SOLICIT
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
sol->setRemoteAddr(IOAddress("fe80::abcd"));
sol->setIface("eth0");
boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_NA, 234, 1500, 3000);
// with a valid hint
......@@ -546,6 +547,7 @@ TEST_F(Dhcpv6SrvTest, SolicitInvalidHint) {
// Let's create a SOLICIT
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
sol->setRemoteAddr(IOAddress("fe80::abcd"));
sol->setIface("eth0");
boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_NA, 234, 1500, 3000);
IOAddress hint("2001:db8:1::cafe:babe");
ASSERT_FALSE(subnet_->inPool(Lease::TYPE_NA, hint));
......@@ -596,6 +598,10 @@ TEST_F(Dhcpv6SrvTest, ManySolicits) {
sol2->setRemoteAddr(IOAddress("fe80::1223"));
sol3->setRemoteAddr(IOAddress("fe80::3467"));
sol1->setIface("eth0");
sol2->setIface("eth0");
sol3->setIface("eth0");
sol1->addOption(generateIA(D6O_IA_NA, 1, 1500, 3000));
sol2->addOption(generateIA(D6O_IA_NA, 2, 1500, 3000));
sol3->addOption(generateIA(D6O_IA_NA, 3, 1500, 3000));
......@@ -673,6 +679,7 @@ TEST_F(Dhcpv6SrvTest, RequestBasic) {
// Let's create a REQUEST
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_REQUEST, 1234));
req->setRemoteAddr(IOAddress("fe80::abcd"));
req->setIface("eth0");
boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_NA, 234, 1500, 3000);
// with a valid hint
......@@ -737,6 +744,7 @@ TEST_F(Dhcpv6SrvTest, pdRequestBasic) {
// Let's create a REQUEST
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_REQUEST, 1234));
req->setRemoteAddr(IOAddress("fe80::abcd"));
req->setIface("eth0");
boost::shared_ptr<Option6IA> ia = generateIA(D6O_IA_PD, 234, 1500, 3000);
// with a valid hint
......@@ -800,6 +808,10 @@ TEST_F(Dhcpv6SrvTest, ManyRequests) {
req2->setRemoteAddr(IOAddress("fe80::1223"));
req3->setRemoteAddr(IOAddress("fe80::3467"));
req1->setIface("eth0");
req2->setIface("eth0");
req3->setIface("eth0");
req1->addOption(generateIA(D6O_IA_NA, 1, 1500, 3000));
req2->addOption(generateIA(D6O_IA_NA, 2, 1500, 3000));
req3->addOption(generateIA(D6O_IA_NA, 3, 1500, 3000));
......@@ -1078,9 +1090,9 @@ TEST_F(Dhcpv6SrvTest, sanityCheck) {
// Check that the server is testing if server identifier received in the
// query, matches server identifier used by the server.
TEST_F(Dhcpv6SrvTest, testServerID) {
NakedDhcpv6Srv srv(0);
NakedDhcpv6Srv srv(0);
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_REQUEST, 1234));
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_REQUEST, 1234));