Commit 2a604994 authored by Francis Dupont's avatar Francis Dupont
Browse files

[master] Finishing merge of trac5404 (port relay)

parents a704f95f 95544131
1382. [func] fdupont
Added support for generalized UDP Source Port for DHCP Relay
(RFC 8357) for DHCPv4, DHCPv6 and DHCPv4-over-DHCPv6. Note
this required changes to the inter-server protocol used by
our 4o6 implementation, and is therefore not backwardly
compatible.
(Trac #5404, git xxx)
1381. [bug] marcin
Corrected a bug in the libkea-asiolink library which caused
the DHCP servers to crash while processing commands over
......
......@@ -2996,7 +2996,8 @@ It is merely echoed by the server
<para>DHCPv4-over-DHCPv6 support is experimental and the
details of the inter-process communication can change: both
the DHCPv4 and DHCPv6 sides should be running the same version
of Kea.</para>
of Kea. For instance the support of port relay (RFC 8357) introduced
such incompatible change.</para>
</note>
<para>
The <command>dhcp4o6-port</command> global parameter specifies
......
......@@ -2718,6 +2718,8 @@ should include options from the isc option space:
DHCPv4-over-DHCPv6 support is experimental and the details of
the inter-process communication can change: both the
DHCPv4 and DHCPv6 sides should be running the same version of Kea.
For instance the support of port relay (RFC 8357) introduced such
such incompatible change.
</note>
<para>
There is only one specific parameter for the DHCPv6 side:
......
......@@ -207,11 +207,11 @@ A malformed DHCPv4o6 packet was received.
This debug message is printed when the server is receiving a DHCPv4o6
from the DHCPv4 server over inter-process communication.
% DHCP4_DHCP4O6_PACKET_SEND %1: trying to send packet %2 (type %3) to %4 on interface %5 encapsulating %6: %7 (type %8)
% DHCP4_DHCP4O6_PACKET_SEND %1: trying to send packet %2 (type %3) to %4 port %5 on interface %6 encapsulating %7: %8 (type %9)
The arguments specify the client identification information (HW address
and client identifier), DHCPv6 message name and type, source IPv6
address and interface name, DHCPv4 client identification, message
name and type.
address and port, and interface name, DHCPv4 client identification,
message name and type.
% DHCP4_DHCP4O6_PACKET_SEND_FAIL %1: failed to send DHCPv4o6 packet: %2
This error is output if the IPv4 DHCP server fails to send an
......@@ -755,3 +755,10 @@ will drop its message if the received message was DHCPDISCOVER,
and will send DHCPNAK if the received message was DHCPREQUEST.
The argument includes the client and the transaction identification
information.
<<<<<<< HEAD
=======
% DHCP6_DHCP4O6_PACKET_RECEIVED received DHCPv4o6 packet from DHCPv6 server (type %1) for %2 port %3 on interface %4
This debug message is printed when the server is receiving a DHCPv4o6
from the DHCPv6 server over inter-process communication.
>>>>>>> trac5404
......@@ -211,10 +211,11 @@ Dhcpv4Exchange::initResponse4o6() {
if (!query6->relay_info_.empty()) {
resp6->copyRelayInfo(query6);
}
// Copy interface and remote address
// Copy interface, and remote address and port
resp6->setIface(query6->getIface());
resp6->setIndex(query6->getIndex());
resp6->setRemoteAddr(query6->getRemoteAddr());
resp6->setRemotePort(query6->getRemotePort());
resp_.reset(new Pkt4o6(resp_, resp6));
}
......@@ -2206,6 +2207,19 @@ Dhcpv4Srv::assignLease(Dhcpv4Exchange& ex) {
}
}
uint16_t
Dhcpv4Srv::checkRelayPort(const Dhcpv4Exchange& ex) {
// Look for a relay-port RAI sub-option in the query.
const Pkt4Ptr& query = ex.getQuery();
const OptionPtr& rai = query->getOption(DHO_DHCP_AGENT_OPTIONS);
if (rai && rai->getOption(RAI_OPTION_RELAY_PORT)) {
// Got the sub-option so use the remote port set by the relay.
return (query->getRemotePort());
}
return (0);
}
void
Dhcpv4Srv::adjustIfaceData(Dhcpv4Exchange& ex) {
adjustRemoteAddr(ex);
......@@ -2232,7 +2246,9 @@ Dhcpv4Srv::adjustIfaceData(Dhcpv4Exchange& ex) {
response->setRemotePort(DHCP4_CLIENT_PORT);
} else {
response->setRemotePort(DHCP4_SERVER_PORT);
// RFC 8357 section 5.1
uint16_t relay_port = checkRelayPort(ex);
response->setRemotePort(relay_port ? relay_port : DHCP4_SERVER_PORT);
}
CfgIfacePtr cfg_iface = CfgMgr::instance().getCurrentCfg()->getCfgIface();
......
......@@ -719,6 +719,12 @@ protected:
/// server's response.
static void appendServerID(Dhcpv4Exchange& ex);
/// @brief Check if the relay port RAI sub-option was set in the query.
///
/// @param ex The exchange holding the client's message
/// @return the port to use to join the relay or 0 for the default
static uint16_t checkRelayPort(const Dhcpv4Exchange& ex);
/// @brief Set IP/UDP and interface parameters for the DHCPv4 response.
///
/// This method sets the following parameters for the DHCPv4 message being
......
......@@ -66,6 +66,7 @@ void Dhcp4to6Ipc::handler() {
LOG_DEBUG(packet4_logger, DBG_DHCP4_BASIC, DHCP4_DHCP4O6_PACKET_RECEIVED)
.arg(static_cast<int>(pkt->getType()))
.arg(pkt->getRemoteAddr().toText())
.arg(pkt->getRemotePort())
.arg(pkt->getIface());
}
} catch (const std::exception& e) {
......@@ -155,6 +156,7 @@ void Dhcp4to6Ipc::handler() {
.arg(rsp6->getName())
.arg(static_cast<int>(rsp6->getType()))
.arg(rsp6->getRemoteAddr())
.arg(rsp6->getRemotePort())
.arg(rsp6->getIface())
.arg(rsp->getLabel())
.arg(rsp->getName())
......
......@@ -162,6 +162,9 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataRelay) {
req->setIface("eth1");
req->setIndex(1);
// Set remote port (it will be used in the next test).
req->setRemotePort(1234);
// Create the exchange using the req.
Dhcpv4Exchange ex = createExchange(req);
......@@ -205,6 +208,75 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataRelay) {
EXPECT_EQ("192.0.1.50", resp->getRemoteAddr().toText());
}
// This test verifies that the remote port is adjusted when
// the query carries a relay port RAI sub-option.
TEST_F(Dhcpv4SrvTest, adjustIfaceDataRelayPort) {
IfaceMgrTestConfig test_config(true);
IfaceMgr::instance().openSockets4();
// Create the instance of the incoming packet.
boost::shared_ptr<Pkt4> req(new Pkt4(DHCPDISCOVER, 1234));
// Set the giaddr to non-zero address and hops to non-zero value
// as if it was relayed.
req->setGiaddr(IOAddress("192.0.1.1"));
req->setHops(2);
// Set ciaddr to zero. This simulates the client which applies
// for the new lease.
req->setCiaddr(IOAddress("0.0.0.0"));
// Clear broadcast flag.
req->setFlags(0x0000);
// Set local address, port and interface.
req->setLocalAddr(IOAddress("192.0.2.5"));
req->setLocalPort(1001);
req->setIface("eth1");
req->setIndex(1);
// Set remote port.
req->setRemotePort(1234);
// Add a RAI relay-port sub-option (the only difference with the previous test).
OptionDefinitionPtr rai_def =
LibDHCP::getOptionDef(DHCP4_OPTION_SPACE, DHO_DHCP_AGENT_OPTIONS);
ASSERT_TRUE(rai_def);
OptionCustomPtr rai(new OptionCustom(*rai_def, Option::V4));
ASSERT_TRUE(rai);
req->addOption(rai);
OptionPtr relay_port(new Option(Option::V4, RAI_OPTION_RELAY_PORT));
ASSERT_TRUE(relay_port);
rai->addOption(relay_port);
// Create the exchange using the req.
Dhcpv4Exchange ex = createExchange(req);
Pkt4Ptr resp = ex.getResponse();
resp->setYiaddr(IOAddress("192.0.1.100"));
// Clear the remote address.
resp->setRemoteAddr(IOAddress("0.0.0.0"));
// Set hops value for the response.
resp->setHops(req->getHops());
// Set the remote port to 67 as we know it will be updated.
resp->setRemotePort(67);
// This function never throws.
ASSERT_NO_THROW(NakedDhcpv4Srv::adjustIfaceData(ex));
// Now the destination address should be relay's address.
EXPECT_EQ("192.0.1.1", resp->getRemoteAddr().toText());
// The query has been relayed, so the response should be sent to the
// port 67, but here there is a relay port RAI so another value is used.
EXPECT_EQ(1234, resp->getRemotePort());
// Local address should be the address assigned to interface eth1.
EXPECT_EQ("192.0.2.5", resp->getLocalAddr().toText());
// The local port is always DHCPv4 server port 67.
EXPECT_EQ(DHCP4_SERVER_PORT, resp->getLocalPort());
// We will send response over the same interface which was used to receive
// query.
EXPECT_EQ("eth1", resp->getIface());
EXPECT_EQ(1, resp->getIndex());
}
// This test verifies that it is possible to configure the server to use
// routing information to determine the right outbound interface to sent
// responses to a relayed client.
......
......@@ -232,7 +232,7 @@ received in Decline message. It's expected that the option will contain an
address that is being declined. Specific information will be printed in a
separate message.
% DHCP6_DHCP4O6_PACKET_RECEIVED received DHCPv4o6 packet from DHCPv4 server (type %1) for %2 on interface %3
% DHCP6_DHCP4O6_PACKET_RECEIVED received DHCPv4o6 packet from DHCPv4 server (type %1) for %2 port %3 on interface %4
This debug message is printed when the server is receiving a DHCPv4o6
from the DHCPv4 server over inter-process communication.
......
// Copyright (C) 2011-2017 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2011-2018 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
......@@ -791,7 +791,8 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp) {
rsp->setRemotePort(DHCP6_CLIENT_PORT);
} else {
// Relayed traffic, send back to the relay agent
rsp->setRemotePort(DHCP6_SERVER_PORT);
uint16_t relay_port = checkRelaySourcePort(query);
rsp->setRemotePort(relay_port ? relay_port : DHCP6_SERVER_PORT);
}
rsp->setLocalPort(DHCP6_SERVER_PORT);
......@@ -3464,6 +3465,22 @@ void Dhcpv6Srv::processRSOO(const Pkt6Ptr& query, const Pkt6Ptr& rsp) {
}
}
uint16_t Dhcpv6Srv::checkRelaySourcePort(const Pkt6Ptr& query) {
if (query->relay_info_.empty()) {
// No relay agent
return (0);
}
// Did the last relay agent add a relay-source-port?
if (query->getRelayOption(D6O_RELAY_SOURCE_PORT, 0)) {
// RFC 8357 section 5.2
return (query->getRemotePort());
}
return (0);
}
void Dhcpv6Srv::processStatsReceived(const Pkt6Ptr& query) {
// Note that we're not bumping pkt6-received statistic as it was
// increased early in the packet reception code.
......
// Copyright (C) 2011-2017 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2011-2018 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
......@@ -758,6 +758,16 @@ protected:
void setStatusCode(boost::shared_ptr<Option6IA>& container,
const OptionPtr& status);
public:
/// Used for DHCPv4-over-DHCPv6 too.
/// @brief Check if the last relay added a relay-source-port option.
///
/// @param query DHCPv6 message to be checked.
/// @return the port to use to join the relay or 0 for the default.
static uint16_t checkRelaySourcePort(const Pkt6Ptr& query);
private:
/// @public
......
// Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2015-2018 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
......@@ -64,6 +64,7 @@ void Dhcp6to4Ipc::handler() {
LOG_DEBUG(packet6_logger, DBG_DHCP6_BASIC, DHCP6_DHCP4O6_PACKET_RECEIVED)
.arg(static_cast<int>(pkt->getType()))
.arg(pkt->getRemoteAddr().toText())
.arg(pkt->getRemotePort())
.arg(pkt->getIface());
}
} catch (const std::exception& e) {
......@@ -77,6 +78,9 @@ void Dhcp6to4Ipc::handler() {
// Should we check it is a DHCPV6_DHCPV4_RESPONSE?
// Handle relay port
uint16_t relay_port = Dhcpv6Srv::checkRelaySourcePort(pkt);
// The received message has been unpacked by the receive() function. This
// method could have modified the message so it's better to pack() it
// again because we'll be forwarding it to a client.
......@@ -89,7 +93,7 @@ void Dhcp6to4Ipc::handler() {
// getType() always returns the type of internal message.
uint8_t msg_type = buf[0];
if ((msg_type == DHCPV6_RELAY_FORW) || (msg_type == DHCPV6_RELAY_REPL)) {
pkt->setRemotePort(DHCP6_SERVER_PORT);
pkt->setRemotePort(relay_port ? relay_port : DHCP6_SERVER_PORT);
} else {
pkt->setRemotePort(DHCP6_CLIENT_PORT);
}
......
......@@ -1572,6 +1572,97 @@ TEST_F(Dhcpv6SrvTest, portsRelayedTraffic) {
EXPECT_EQ(DHCP6_SERVER_PORT, adv->getRemotePort());
}
// Test that the server processes relay-source-port option correctly.
TEST_F(Dhcpv6SrvTest, relaySourcePort) {
NakedDhcpv6Srv srv(0);
string config =
"{"
" \"preferred-lifetime\": 3000,"
" \"rebind-timer\": 2000, "
" \"renew-timer\": 1000, "
" \"subnet6\": [ { "
" \"pools\": [ { \"pool\": \"2001:db8::/64\" } ],"
" \"subnet\": \"2001:db8::/48\" "
" } ],"
" \"valid-lifetime\": 4000"
"}";
EXPECT_NO_THROW(configure(config, srv));
// Create a solicit
Pkt6Ptr sol(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);
// Pretend the packet came via one relay.
Pkt6::RelayInfo relay;
relay.msg_type_ = DHCPV6_RELAY_FORW;
relay.hop_count_ = 1;
relay.linkaddr_ = IOAddress("2001:db8::1");
relay.peeraddr_ = IOAddress("fe80::1");
// Set the source port
sol->setRemotePort(1234);
// Simulate that we have received that traffic
sol->pack();
// Add a relay-source-port option
OptionBuffer zero(2, 0);
OptionPtr opt(new Option(Option::V6, D6O_RELAY_SOURCE_PORT, zero));
relay.options_.insert(make_pair(opt->getType(), opt));
sol->relay_info_.push_back(relay);
// Simulate that we have received that traffic
sol->pack();
EXPECT_EQ(DHCPV6_RELAY_FORW, sol->getBuffer()[0]);
Pkt6Ptr query(new Pkt6(static_cast<const uint8_t*>
(sol->getBuffer().getData()),
sol->getBuffer().getLength()));
query->setRemoteAddr(sol->getRemoteAddr());
query->setRemotePort(sol->getRemotePort());
query->setLocalAddr(sol->getLocalAddr());
query->setLocalPort(sol->getLocalPort());
query->setIface(sol->getIface());
srv.fakeReceive(query);
// Server will now process to run its normal loop, but instead of calling
// IfaceMgr::receive6(), it will read all packets from the list set by
// fakeReceive()
srv.run();
// Check trace of processing
EXPECT_EQ(1234, query->getRemotePort());
ASSERT_EQ(1, query->relay_info_.size());
EXPECT_TRUE(query->getRelayOption(D6O_RELAY_SOURCE_PORT, 0));
// Get Response...
ASSERT_FALSE(srv.fake_sent_.empty());
Pkt6Ptr rsp = srv.fake_sent_.front();
ASSERT_TRUE(rsp);
// Check it
EXPECT_EQ(1234, rsp->getRemotePort());
EXPECT_EQ(DHCPV6_RELAY_REPL, rsp->getBuffer()[0]);
// Get Advertise
Pkt6Ptr adv(new Pkt6(static_cast<const uint8_t*>
(rsp->getBuffer().getData()),
rsp->getBuffer().getLength()));
adv->unpack();
// Check it
EXPECT_EQ(DHCPV6_ADVERTISE, adv->getType());
ASSERT_EQ(1, adv->relay_info_.size());
EXPECT_TRUE(adv->getRelayOption(D6O_RELAY_SOURCE_PORT, 0));
}
// Checks effect of persistency (aka always-true) flag on the ORO
TEST_F(Dhcpv6SrvTest, prlPersistency) {
IfaceMgrTestConfig test_config(true);
......
/*
* Copyright (C) 2004-2017 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2004-2018 Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
* This Source Code Form is subject to the terms of the Mozilla Public
......@@ -273,6 +273,7 @@ static const uint16_t RAI_OPTION_ACCESS_POINT_NAME = 15; // RFC7839
static const uint16_t RAI_OPTION_ACCESS_POINT_BSSID = 16; // RFC7839
static const uint16_t RAI_OPTION_OPERATOR_ID = 17; // RFC7839
static const uint16_t RAI_OPTION_OPERATOR_REALM = 18; // RFC7839
static const uint16_t RAI_OPTION_RELAY_PORT = 19; // RFC8357
static const uint16_t RAI_OPTION_VIRTUAL_SUBNET_SELECT = 151; //RFC6607
static const uint16_t RAI_OPTION_VIRTUAL_SUBNET_SELECT_CTRL = 152; //RFC6607
......
......@@ -152,7 +152,8 @@ enum DHCPv6OptionType {
// D6O_F_SERVER_STATE = 132, /* RFC8156 */
// D6O_F_START_TIME_OF_STATE = 133, /* RFC8156 */
// D6O_F_STATE_EXPIRATION_TIME = 134, /* RFC8156 */
// 135-142 unassigned
D6O_RELAY_SOURCE_PORT = 135, /* RFC8357 */
// 136-142 unassigned
D6O_IPV6_ADDRESS_ANDSF = 143, /* RFC6153 */
// The following are EXPERIMENTAL and may change when IANA assigns official
......@@ -278,6 +279,7 @@ static const uint32_t ENTERPRISE_ID_ISC = 2495;
codes for the ISC vendor specific options used in 4o6 */
static const uint16_t ISC_V6_4O6_INTERFACE = 60000;
static const uint16_t ISC_V6_4O6_SRC_ADDRESS = 60001;
static const uint16_t ISC_V6_4O6_SRC_PORT = 60002;
/* Offsets into IA_*'s where Option spaces commence. */
static const uint16_t IA_NA_OFFSET = 12; /* IAID, T1, T2, all 4 octets each */
......
......@@ -794,6 +794,12 @@ void Pkt6::copyRelayInfo(const Pkt6Ptr& question) {
info.options_.insert(make_pair(opt->getType(), opt));
}
// Same for relay-source-port option
opt = question->getNonCopiedRelayOption(D6O_RELAY_SOURCE_PORT, i);
if (opt) {
info.options_.insert(make_pair(opt->getType(), opt));
}
/// @todo: Implement support for ERO (Echo Request Option, RFC4994)
// Add this relay-forw info (client's message) to our relay-repl
......
......@@ -444,6 +444,7 @@ const OptionDefParams STANDARD_V6_OPTION_DEFINITIONS[] = {
NO_RECORD_DEF, "" },
{ "v6-captive-portal", D6O_V6_CAPTIVE_PORTAL, OPT_STRING_TYPE, false,
NO_RECORD_DEF, "" },
{ "relay-source-port", D6O_RELAY_SOURCE_PORT, OPT_UINT16_TYPE, false, NO_RECORD_DEF, "" },
{ "ipv6-address-andsf", D6O_IPV6_ADDRESS_ANDSF, OPT_IPV6_ADDRESS_TYPE, true,
NO_RECORD_DEF, "" },
{ "public-key", D6O_PUBLIC_KEY, OPT_BINARY_TYPE, false,
......@@ -489,7 +490,9 @@ const OptionDefParams ISC_V6_OPTION_DEFINITIONS[] = {
{ "4o6-interface", ISC_V6_4O6_INTERFACE, OPT_STRING_TYPE, false,
NO_RECORD_DEF, "" },
{ "4o6-source-address", ISC_V6_4O6_SRC_ADDRESS, OPT_IPV6_ADDRESS_TYPE,
false, NO_RECORD_DEF, "" }
false, NO_RECORD_DEF, "" },
{ "4o6-source-port", ISC_V6_4O6_SRC_PORT, OPT_UINT16_TYPE, false,
NO_RECORD_DEF, "" }
};
const int ISC_V6_OPTION_DEFINITIONS_SIZE =
......
......@@ -1736,6 +1736,9 @@ TEST_F(LibDhcpTest, stdOptionDefs6) {
LibDhcpTest::testStdOptionDefs6(D6O_V6_CAPTIVE_PORTAL, begin, end,
typeid(OptionString));
LibDhcpTest::testStdOptionDefs6(D6O_RELAY_SOURCE_PORT, begin, begin + 2,
typeid(OptionInt<uint16_t>));
LibDhcpTest::testStdOptionDefs6(D6O_IPV6_ADDRESS_ANDSF, begin, end,
typeid(Option6AddrLst));
......
// Copyright (C) 2015-2016 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2015-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
......@@ -10,6 +10,7 @@
#include <dhcp/iface_mgr.h>
#include <dhcp/option6_addrlst.h>
#include <dhcp/option_custom.h>
#include <dhcp/option_int.h>
#include <dhcp/option_string.h>
#include <dhcp/option_vendor.h>
#include <dhcpsrv/dhcp4o6_ipc.h>
......@@ -191,14 +192,27 @@ Pkt6Ptr Dhcp4o6IpcBase::receive() {
"or has incorrect type)");
}
// Get the option holding source port.
OptionUint16Ptr sport = boost::dynamic_pointer_cast<
OptionUint16>(option_vendor->getOption(ISC_V6_4O6_SRC_PORT));
if (!sport) {
LOG_WARN(dhcpsrv_logger, DHCPSRV_DHCP4O6_RECEIVED_BAD_PACKET)
.arg("no source port suboption");
isc_throw(Dhcp4o6IpcError,
"malformed packet (source port suboption missing "
"or has incorrect type)");
}
// Update the packet.
pkt->setRemoteAddr(srcs->readAddress());
pkt->setRemotePort(sport->getValue());
pkt->setIface(iface->getName());
pkt->setIndex(iface->getIndex());
// Remove options that have been added by the IPC sender.
static_cast<void>(option_vendor->delOption(ISC_V6_4O6_INTERFACE));
static_cast<void>(option_vendor->delOption(ISC_V6_4O6_SRC_ADDRESS));
static_cast<void>(option_vendor->delOption(ISC_V6_4O6_SRC_PORT));
// If there are no more options, the IPC sender has probably created the
// vendor option, in which case we should remove it here.
......@@ -243,6 +257,9 @@ void Dhcp4o6IpcBase::send(const Pkt6Ptr& pkt) {
option_vendor->addOption(Option6AddrLstPtr(new Option6AddrLst(
ISC_V6_4O6_SRC_ADDRESS,
pkt->getRemoteAddr())));
option_vendor->addOption(OptionUint16Ptr(new OptionUint16(Option::V6,
ISC_V6_4O6_SRC_PORT,
pkt->getRemotePort())));
// Get packet content
OutputBuffer& buf = pkt->getBuffer();
buf.clear();
......
// Copyright (C) 2015-2016 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2015-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
......@@ -54,10 +54,10 @@ public:
/// the original DHCPv4 query message sent by the client. This
/// information is known by the DHCPv6 server and needs to be conveyed
/// to the DHCPv4 server. The IPC conveys it in the
/// @c ISC_V6_4O6_INTERFACE and @c ISC_V6_4O6_SRC_ADDRESS options
/// within the Vendor Specific Information option, with ISC
/// enterprise id. These options are added by the IPC sender and removed
/// by the IPC receiver.
/// @c ISC_V6_4O6_INTERFACE, @c ISC_V6_4O6_SRC_ADDRESS and @c
/// ISC_V6_4O6_SRC_PORT options within the Vendor Specific Information
/// option, with ISC enterprise id. These options are added by the IPC
/// sender and removed by the IPC receiver.
class Dhcp4o6IpcBase : public boost::noncopyable {
public:
......@@ -105,11 +105,11 @@ public:
/// @brief Send message over IPC.
///
/// The IPC uses @c ISC_V6_4O6_INTERFACE and @c ISC_V6_4O6_SRC_ADDRESS
/// options conveyed within the Vendor Specific Information option, with
/// ISC enterprise id, to communicate the client remote address and the
/// interface on which the DHCPv4 query was received. These options will
/// be removed by the receiver.
/// The IPC uses @c ISC_V6_4O6_INTERFACE, @c ISC_V6_4O6_SRC_ADDRESS
/// and @c ISC_V6_4O6_SRC_PORT options conveyed within the Vendor
/// Specific Information option, with ISC enterprise id, to communicate
/// the client remote address and the interface on which the DHCPv4 query
/// was received. These options will be removed by the receiver.
///
/// @param pkt Pointer to a DHCPv6 message with interface and remote
/// address.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment