Skip to content

Commit

Permalink
[#2022] Finished RADIUS v6 server code
Browse files Browse the repository at this point in the history
  • Loading branch information
fxdupont committed Feb 5, 2024
1 parent 3b9cecf commit 89a34ee
Show file tree
Hide file tree
Showing 8 changed files with 224 additions and 171 deletions.
82 changes: 57 additions & 25 deletions src/bin/dhcp6/dhcp6_srv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -421,9 +421,9 @@ Dhcpv6Srv::setHostIdentifiers(AllocEngine::ClientContext6& ctx) {
}
}

bool
Dhcpv6Srv::earlyGHRLookup(const Pkt6Ptr& query,
AllocEngine::ClientContext6& ctx) {
void
Dhcpv6Srv::initContext0(const Pkt6Ptr& query,
AllocEngine::ClientContext6& ctx) {
// Pointer to client's query.
ctx.query_ = query;

Expand All @@ -432,6 +432,13 @@ Dhcpv6Srv::earlyGHRLookup(const Pkt6Ptr& query,

// Hardware address.
ctx.hwaddr_ = getMAC(query);
}

bool
Dhcpv6Srv::earlyGHRLookup(const Pkt6Ptr& query,
AllocEngine::ClientContext6& ctx) {
// First part of context initialization.
initContext0(query, ctx);

// Get the early-global-reservations-lookup flag value.
data::ConstElementPtr egrl = CfgMgr::instance().getCurrentCfg()->
Expand Down Expand Up @@ -492,15 +499,16 @@ Dhcpv6Srv::earlyGHRLookup(const Pkt6Ptr& query,
}

void
Dhcpv6Srv::initContext(const Subnet6Ptr& subnet,
const Pkt6Ptr& pkt,
AllocEngine::ClientContext6& ctx,
bool& drop) {
ctx.subnet_ = subnet;
Dhcpv6Srv::initContext(AllocEngine::ClientContext6& ctx, bool& drop) {
// Sanity check.
if (!ctx.query_) {
drop = true;
return;
}
ctx.fwd_dns_update_ = false;
ctx.rev_dns_update_ = false;
ctx.hostname_ = "";
ctx.callout_handle_ = getCalloutHandle(pkt);
ctx.callout_handle_ = getCalloutHandle(ctx.query_);

// Collect host identifiers if host reservations enabled. The identifiers
// are stored in order of preference. The server will use them in that
Expand Down Expand Up @@ -545,37 +553,37 @@ Dhcpv6Srv::initContext(const Subnet6Ptr& subnet,
// a result, the first_class set via the host reservation will
// replace the second_class because the second_class will this
// time evaluate to false as desired.
removeDependentEvaluatedClasses(pkt);
setReservedClientClasses(pkt, ctx);
evaluateClasses(pkt, false);
removeDependentEvaluatedClasses(ctx.query_);
setReservedClientClasses(ctx.query_, ctx);
evaluateClasses(ctx.query_, false);
}

// Set KNOWN builtin class if something was found, UNKNOWN if not.
if (!ctx.hosts_.empty()) {
pkt->addClass("KNOWN");
ctx.query_->addClass("KNOWN");
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_CLASS_ASSIGNED)
.arg(pkt->getLabel())
.arg(ctx.query_->getLabel())
.arg("KNOWN");
} else {
pkt->addClass("UNKNOWN");
ctx.query_->addClass("UNKNOWN");
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_CLASS_ASSIGNED)
.arg(pkt->getLabel())
.arg(ctx.query_->getLabel())
.arg("UNKNOWN");
}

// Perform second pass of classification.
evaluateClasses(pkt, true);
evaluateClasses(ctx.query_, true);

const ClientClasses& classes = pkt->getClasses();
const ClientClasses& classes = ctx.query_->getClasses();
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_CLASSES_ASSIGNED_AFTER_SUBNET_SELECTION)
.arg(pkt->getLabel())
.arg(ctx.query_->getLabel())
.arg(classes.toText());

// Check the DROP special class.
if (pkt->inClass("DROP")) {
if (ctx.query_->inClass("DROP")) {
LOG_DEBUG(packet6_logger, DBGLVL_PKT_HANDLING, DHCP6_PACKET_DROP_DROP_CLASS2)
.arg(pkt->makeLabel(pkt->getClientId(), nullptr))
.arg(pkt->toText());
.arg(ctx.query_->makeLabel(ctx.query_->getClientId(), 0))
.arg(ctx.query_->toText());
StatsMgr::instance().addValue("pkt6-receive-drop",
static_cast<int64_t>(1));
drop = true;
Expand Down Expand Up @@ -968,15 +976,39 @@ Dhcpv6Srv::processDhcp6Query(Pkt6Ptr query) {

// Complete the client context initialization.
bool drop = false;
Subnet6Ptr subnet = selectSubnet(query, drop);
ctx.subnet_ = selectSubnet(query, drop);
if (drop) {
// Caller will immediately drop the packet so simply return now.
return (Pkt6Ptr());
}

// Park point here.
return (processLocalizedQuery6(ctx));
}

void
Dhcpv6Srv::processLocalizedQuery6AndSendResponse(Pkt6Ptr query,
AllocEngine::ClientContext6& ctx) {
try {
Pkt6Ptr rsp = processLocalizedQuery6(ctx);
if (!rsp) {
return;
}

CalloutHandlePtr callout_handle = getCalloutHandle(query);
processPacketBufferSend(callout_handle, rsp);
} catch (const std::exception& e) {
LOG_ERROR(packet6_logger, DHCP6_PACKET_PROCESS_STD_EXCEPTION)
.arg(e.what());
} catch (...) {
LOG_ERROR(packet6_logger, DHCP6_PACKET_PROCESS_EXCEPTION);
}
}

initContext(subnet, query, ctx, drop);
Pkt6Ptr
Dhcpv6Srv::processLocalizedQuery6(AllocEngine::ClientContext6& ctx) {
Pkt6Ptr query = ctx.query_;
bool drop = false;
initContext(ctx, drop);
// Stop here if initContext decided to drop the packet.
if (drop) {
return (Pkt6Ptr());
Expand Down
41 changes: 31 additions & 10 deletions src/bin/dhcp6/dhcp6_srv.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,28 +175,47 @@ class Dhcpv6Srv : public process::Daemon {

/// @brief Process a single incoming DHCPv6 packet.
///
/// It verifies correctness of the passed packet, calls per-type processXXX
/// methods, generates appropriate answer.
/// It verifies correctness of the passed packet, localizes it,
/// calls per-type processXXX methods, generates appropriate answer.
///
/// @param query A pointer to the packet to be processed.
/// @return A pointer to the response.
Pkt6Ptr processPacket(Pkt6Ptr query);

/// @brief Process a single incoming DHCPv6 query.
///
/// It calls per-type processXXX methods, generates appropriate answer.
/// It localizes the query, calls per-type processXXX methods,
/// generates appropriate answer.
///
/// @param query A pointer to the packet to be processed.
/// @return A pointer to the response.
Pkt6Ptr processDhcp6Query(Pkt6Ptr query);

/// @brief Process a single incoming DHCPv6 query.
///
/// It localizes the query, calls per-type processXXX methods,
/// generates appropriate answer, sends the answer to the client.
///
/// @param query A pointer to the packet to be processed.
void processDhcp6QueryAndSendResponse(Pkt6Ptr query);

/// @brief Process a localized incoming DHCPv6 query.
///
/// It calls per-type processXXX methods, generates appropriate answer.
///
/// @param ctx Pointer to The client context.
/// @return A pointer to the response.
Pkt6Ptr processLocalizedQuery6(AllocEngine::ClientContext6& ctx);

/// @brief Process a localized incoming DHCPv6 query.
///
/// It calls per-type processXXX methods, generates appropriate answer,
/// sends the answer to the client.
///
/// @param query A pointer to the packet to be processed.
void processDhcp6QueryAndSendResponse(Pkt6Ptr query);
/// @param ctx Pointer to The client context.
void processLocalizedQuery6AndSendResponse(Pkt6Ptr query,
AllocEngine::ClientContext6& ctx);

/// @brief Instructs the server to shut down.
void shutdown() override;
Expand Down Expand Up @@ -254,6 +273,13 @@ class Dhcpv6Srv : public process::Daemon {
/// Called during reconfigure and shutdown.
void discardPackets();

/// @brief Initialize client context (first part).
///
/// @param query The query message.
/// @param ctx Reference to client context.
void initContext0(const Pkt6Ptr& query,
AllocEngine::ClientContext6& ctx);

/// @brief Initialize client context and perform early global
/// reservations lookup.
///
Expand Down Expand Up @@ -917,14 +943,9 @@ class Dhcpv6Srv : public process::Daemon {
/// the Rapid Commit option was included and that the server respects
/// it.
///
/// @param subnet Selected subnet.
/// @param pkt pointer to a packet for which context will be created.
/// @param [out] ctx reference to context object to be initialized.
/// @param [out] drop if it is true the packet will be dropped.
void initContext(const Subnet6Ptr& subnet,
const Pkt6Ptr& pkt,
AllocEngine::ClientContext6& ctx,
bool& drop);
void initContext(AllocEngine::ClientContext6& ctx, bool& drop);

/// @brief this is a prefix added to the content of vendor-class option
///
Expand Down
Loading

0 comments on commit 89a34ee

Please sign in to comment.