Kea: flex_option_callouts.cc Source File

| Kea 3.2.0-git

flex_option_callouts.cc
Go to the documentation of this file.
1// Copyright (C) 2019-2026 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
9#include <flex_option.h>
10#include <flex_option_log.h>
11#include <cc/command_interpreter.h>
12#include <hooks/hooks.h>
13#include <dhcp/pkt4.h>
14#include <dhcp/pkt6.h>
15#include <dhcpsrv/cfgmgr.h>
16#include <process/daemon.h>
17
18namespace isc {
19namespace flex_option {
20
21 FlexOptionImplPtr impl;
22
23} // end of namespace flex_option
24} // end of namespace isc
25
26using namespace isc;
27using namespace isc::data;
28using namespace isc::dhcp;
29using namespace isc::flex_option;
30using namespace isc::hooks;
31using namespace isc::process;
32
33// Functions accessed by the hooks framework use C linkage to avoid the name
34// mangling that accompanies use of the C++ compiler as well as to avoid
35// issues related to namespaces.
36extern "C" {
37
47 int pkt4_send(CalloutHandle& handle) {
48 CalloutHandle::CalloutNextStep status = handle.getStatus();
49 if (status == CalloutHandle::NEXT_STEP_DROP) {
50 return (0);
51 }
52
53 // Sanity.
54 if (!impl) {
55 return (0);
56 }
57
58 // Get the parameters.
59 Pkt4Ptr query;
60 Pkt4Ptr response;
61 handle.getArgument("query4", query);
62 handle.getArgument("response4", response);
63
64 if (status == CalloutHandle::NEXT_STEP_SKIP) {
65 isc_throw(InvalidOperation, "packet pack already handled");
66 }
67
68 try {
69 impl->process<Pkt4Ptr>(Option::V4, query, response);
70 } catch (const std::exception& ex) {
71 LOG_ERROR(flex_option_logger, FLEX_OPTION_PROCESS_ERROR)
72 .arg(query->getLabel())
73 .arg(ex.what());
74 }
75
76 return (0);
77}
78
88 int pkt6_send(CalloutHandle& handle) {
89 CalloutHandle::CalloutNextStep status = handle.getStatus();
90 if (status == CalloutHandle::NEXT_STEP_DROP) {
91 return (0);
92 }
93
94 // Sanity.
95 if (!impl) {
96 return (0);
97 }
98
99 if (status == CalloutHandle::NEXT_STEP_SKIP) {
100 isc_throw(InvalidOperation, "packet pack already handled");
101 }
102
103 // Get the parameters.
104 Pkt6Ptr query;
105 Pkt6Ptr response;
106 handle.getArgument("query6", query);
107 handle.getArgument("response6", response);
108
109 try {
110 impl->process<Pkt6Ptr>(Option::V6, query, response);
111 } catch (const std::exception& ex) {
112 LOG_ERROR(flex_option_logger, FLEX_OPTION_PROCESS_ERROR)
113 .arg(query->getLabel())
114 .arg(ex.what());
115 }
116
117 return (0);
118}
119
124 int load(LibraryHandle& handle) {
125 try {
126 // Make the hook library not loadable by d2.
127 uint16_t family = CfgMgr::instance().getFamily();
128 const std::string& proc_name = Daemon::getProcName();
129 if (family == AF_INET) {
130 if (proc_name != "kea-dhcp4") {
131 isc_throw(isc::Unexpected, "Bad process name: " << proc_name
132 << ", expected kea-dhcp4");
133 }
134 } else {
135 if (proc_name != "kea-dhcp6") {
136 isc_throw(isc::Unexpected, "Bad process name: " << proc_name
137 << ", expected kea-dhcp6");
138 }
139 }
140
141 impl.reset(new FlexOptionImpl());
142 ConstElementPtr options = handle.getParameter("options");
143 impl->configure(options);
144 } catch (const std::exception& ex) {
145 LOG_ERROR(flex_option_logger, FLEX_OPTION_LOAD_ERROR)
146 .arg(ex.what());
147 return (1);
148 }
149
150 return (0);
151}
152
156 int unload() {
157 impl.reset();
158 LOG_INFO(flex_option_logger, FLEX_OPTION_UNLOAD);
159 return (0);
160}
161
165 int multi_threading_compatible() {
166 return (1);
167}
168
169} // end extern "C"
cfgmgr.h
CalloutHandle::CalloutNextStep
CalloutNextStep
Specifies allowed next steps.
Definition callout_handle.h:86
CalloutHandle::NEXT_STEP_DROP
@ NEXT_STEP_DROP
drop the packet
Definition callout_handle.h:89
CalloutHandle::NEXT_STEP_SKIP
@ NEXT_STEP_SKIP
skip the next processing step
Definition callout_handle.h:88
isc::InvalidOperation
A generic exception that is thrown if a function is called in a prohibited way.
Definition exceptions/exceptions.h:143
isc::Unexpected
A generic exception that is thrown when an unexpected error condition occurs.
Definition exceptions/exceptions.h:153
isc::dhcp::CfgMgr::getFamily
uint16_t getFamily() const
Returns address family.
Definition cfgmgr.h:246
isc::dhcp::CfgMgr::instance
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition cfgmgr.cc:29
isc::dhcp::Option::V6
@ V6
Definition option.h:90
isc::dhcp::Option::V4
@ V4
Definition option.h:90
isc::flex_option::FlexOptionImpl
Flex Option implementation.
Definition flex_option.h:37
isc::hooks::CalloutHandle
Per-packet callout handle.
Definition callout_handle.h:78
isc::hooks::CalloutHandle::getStatus
CalloutNextStep getStatus() const
Returns the next processing step.
Definition callout_handle.h:241
isc::hooks::CalloutHandle::getArgument
void getArgument(const std::string &name, T &value) const
Get argument.
Definition callout_handle.h:164
isc::hooks::LibraryHandle
Library handle.
Definition library_handle.h:60
isc::hooks::LibraryHandle::getParameter
isc::data::ConstElementPtr getParameter(const std::string &name)
Returns configuration parameter for the library.
Definition library_handle.cc:101
isc::process::Daemon::getProcName
static std::string getProcName()
returns the process name This value is used as when forming the default PID file name
Definition daemon.cc:154
command_interpreter.h
This file contains several functions and constants that are used for handling commands and responses ...
daemon.h
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition exceptions/exceptions.h:210
flex_option.h
multi_threading_compatible
int multi_threading_compatible()
This function is called to retrieve the multi-threading compatibility.
Definition flex_option_callouts.cc:165
pkt6_send
int pkt6_send(CalloutHandle &handle)
This callout is called at the "pkt6_send" hook.
Definition flex_option_callouts.cc:88
pkt4_send
int pkt4_send(CalloutHandle &handle)
This callout is called at the "pkt4_send" hook.
Definition flex_option_callouts.cc:47
unload
int unload()
This function is called when the library is unloaded.
Definition flex_option_callouts.cc:156
load
int load(LibraryHandle &handle)
This function is called when the library is loaded.
Definition flex_option_callouts.cc:124
flex_option_log.h
FLEX_OPTION_PROCESS_ERROR
const isc::log::MessageID FLEX_OPTION_PROCESS_ERROR
FLEX_OPTION_LOAD_ERROR
const isc::log::MessageID FLEX_OPTION_LOAD_ERROR
FLEX_OPTION_UNLOAD
const isc::log::MessageID FLEX_OPTION_UNLOAD
hooks.h
LOG_ERROR
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition macros.h:32
LOG_INFO
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition macros.h:20
isc::data
Definition base_stamped_element.cc:12
isc::data::ConstElementPtr
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:30
isc::dhcp
Definition dhcp4/client_handler.cc:20
isc::dhcp::Pkt4Ptr
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
Definition pkt4.h:556
isc::dhcp::Pkt6Ptr
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
Definition pkt6.h:31
isc::flex_option
Definition flex_option.cc:75
isc::flex_option::impl
FlexOptionImplPtr impl
Definition flex_option_callouts.cc:21
isc::flex_option::flex_option_logger
isc::log::Logger flex_option_logger("flex-option-hooks")
Definition flex_option_log.h:18
isc::flex_option::FlexOptionImplPtr
boost::shared_ptr< FlexOptionImpl > FlexOptionImplPtr
The type of shared pointers to Flex Option implementations.
Definition flex_option.h:645
isc::hooks
Definition callout_handle.cc:21
isc::process
Definition cb_ctl_base.h:22
isc
Defines the logger used by the top-level component of kea-lfc.
Definition check_exists_add.cc:18
pkt4.h
pkt6.h