diff --git a/doc/devel/mainpage.dox b/doc/devel/mainpage.dox
index 295fd03986..92f86eb765 100644
--- a/doc/devel/mainpage.dox
+++ b/doc/devel/mainpage.dox
@@ -30,6 +30,7 @@
* - @subpage dhcpv6ConfigInherit
* - @subpage libdhcp
* - @subpage libdhcpIntro
+ * - @subpage libdhcpRelay
* - @subpage libdhcpIfaceMgr
* - @subpage libdhcpsrv
* - @subpage leasemgr
diff --git a/doc/guide/bind10-guide.xml b/doc/guide/bind10-guide.xml
index d0d1d4c3f6..e76839bfcc 100644
--- a/doc/guide/bind10-guide.xml
+++ b/doc/guide/bind10-guide.xml
@@ -4842,35 +4842,77 @@ should include options from the isc option space:
Subnet Selection
- The DHCPv6 server may receive requests from local (connected
- to the same subnet as the server) and remote (connecting via
- relays) clients.
-
-
- Currently relayed DHCPv6 traffic is not supported. The server will
- only respond to local DHCPv6 requests - see
-
-
- As it may have many subnet configurations defined, it
- must select appropriate subnet for a given request. To do this, the server first
+ 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.
+ 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.
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 specified interface. For example
- the server that is intended to serve a local subnet over eth0 may be configured
- as follows:
+ "interface" 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:
> config add Dhcp6/subnet6
> config set Dhcp6/subnet6[1]/subnet "2001:db8:beef::/48"
> config set Dhcp6/subnet6[1]/pool [ "2001:db8:beef::/48" ]
> config set Dhcp6/subnet6[1]/interface "eth0"
> config commit
+
+
+
+
+
+ DHCPv6 Relays
+
+ DHCPv6 server supports remote clients connected via relays. Server
+ that has many subnets defined and receives a request from client, must
+ select appropriate subnet for it. Remote clients there are two
+ mechanisms that can be used here. The first one is based on
+ interface-id options. While forwarding client's message, relays may
+ insert interface-id option that identifies the interface on which the
+ client message was received on. Some relays allow configuration of
+ that parameter, but it is sometimes hardcoded. This may range from
+ very simple (e.g. "vlan100") to very cryptic. One example used by real
+ hardware was "ISAM144|299|ipv6|nt:vp:1:110"). This may seem
+ meaningless, but that information is sufficient for its
+ purpose. Server may use it to select appropriate subnet and the relay
+ will know which interface to use for response transmission when it
+ gets that value back. This value must be unique in the whole
+ network. Server configuration must match whatever values are inserted
+ by the relays.
+
+
+ The second way in which server may pick the proper subnet is by using
+ linkaddr field in the RELAY_FORW message. Name of this field is somewhat
+ misleading. It does not contain link-layer address, but an address that
+ is used to identify a link. This typically is a global address. Kea
+ server checks if that address belongs to any defined subnet6. If it does,
+ that subnet is selected for client's request.
+
+
+ It should be noted that "interface" that defines which local network
+ interface can be used to access a given subnet and "interface-id" that
+ specify the content of the interface-id option used by relays are mutually
+ exclusive. A subnet cannot be both reachable locally (direct traffic) and
+ via relays (remote traffic). Specifying both is a configuration error and
+ Kea server will refuse such configuration.
+
+
+ To specify interface-id with value "vlan123", the following commands can
+ be used:
+
+> config add Dhcp6/subnet6
+> config set Dhcp6/subnet6[0]/subnet "2001:db8:beef::/48"
+> config set Dhcp6/subnet6[0]/pool [ "2001:db8:beef::/48" ]
+> config set Dhcp6/subnet6[0]/interface-id "vland123"
+> config commit
@@ -4940,9 +4982,6 @@ Dhcp6/renew-timer 1000 integer (default)
> config commit
-
- Relayed traffic is not supported.
-
Temporary addresses are not supported.
diff --git a/src/lib/dhcp/libdhcp++.dox b/src/lib/dhcp/libdhcp++.dox
index 194175aa10..eabc3926c7 100644
--- a/src/lib/dhcp/libdhcp++.dox
+++ b/src/lib/dhcp/libdhcp++.dox
@@ -57,6 +57,53 @@ DHCPv6, but is rarely used in DHCPv4. isc::dhcp::Option::addOption(),
isc::dhcp::Option::delOption(), isc::dhcp::Option::getOption() can be used
for that purpose.
+@section libdhcpRelay Relay v6 support in Pkt6
+
+DHCPv6 clients that are not connected to the same link as DHCPv6
+servers need relays to reach the server. Each relay receives a message
+on a client facing interface, encapsulates it into RELAY_MSG option
+and sends as RELAY_FORW message towards the server (or the next relay,
+which is closer to the server). This procedure can be repeated up to
+32 times. Kea is able to support up to 32 relays. Each traversed relay
+may add certain options. The most obvious example is interface-id
+option, but there may be other options as well. Each relay may add such
+an option, regardless of whether other relays added it before. Thanks
+to encapsulation, those options are separated and it is possible to
+differentiate which relay inserted specific instance of an option.
+
+Interface-id is used to identify a subnet (or interface) the original message
+came from and is used for that purpose on two occasions. First, the server
+uses the interface-id included by the first relay (the one closest to
+the client) to select appropriate subnet for a given request. Server includes
+that interface-id in its copy, when sending data back to the client.
+This will be used by the relay to choose proper interface when forwarding
+response towards the client.
+
+Pkt6 class has a public Pkt6::relay_info_ field, which is of type Pkt6::RelayInfo.
+This is a simple structure that represents the information in each RELAY_FORW
+or RELAY_REPL message. It is important to understand the order in which
+the data appear here. Consider the following network:
+
+\verbatim
+client-------relay1-----relay2-----relay3----server
+\endverbatim
+
+Client will transmit SOLICIT message. Relay1 will forward it as
+RELAY_FORW with SOLICIT in it. Relay2 forward it as RELAY_FORW with
+RELAY_FORW with SOLICIT in it. Finally the third relay will add yet
+another RELAY_FORW around it. The server will parse the packet and
+create Pkt6 object for it. Its relay_info_ will have 3
+elements. Packet parsing is done in reverse order, compare to the
+order the packet traversed in the network. The first element
+(relay_info_[0]) will represent relay3 information (the "last" relay or
+in other words the one closest to the server). The second element
+will represent relay2. The third element (relay_info_[2]) will represent
+the first relay (relay1) or in other words the one closest to the client.
+
+Packets sent by the server must maintain the same encapsulation order.
+This is easy to do - just copy data from client's message object into
+server's response object. See Pkt6::coyRelayInfo for details.
+
@section libdhcpIfaceMgr Interface Manager
Interface Manager (or IfaceMgr) is an abstraction layer about low-level