Kea 3.3.1
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>
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
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
48 if ((status == CalloutHandle::NEXT_STEP_SKIP) ||
50 return (0);
51 }
52
53 // Sanity.
54 if (!impl) {
55 return (0);
56 }
57
58 // Get the parameters.
59 Pkt4Ptr query;
60 handle.getArgument("query4", query);
61
62 if (!query) {
63 return (0);
64 }
65
66 try {
67 impl->process<Pkt4Ptr>(Option::V4, query, Pkt4Ptr());
68 } catch (const std::exception& ex) {
70 .arg(query->getLabel())
71 .arg(ex.what());
72 }
73
74 return (0);
75}
76
87 if ((status == CalloutHandle::NEXT_STEP_SKIP) ||
89 return (0);
90 }
91
92 // Sanity.
93 if (!impl) {
94 return (0);
95 }
96
97 // Get the parameters.
98 Pkt6Ptr query;
99 handle.getArgument("query6", query);
100
101 if (!query) {
102 return (0);
103 }
104
105 try {
106 impl->process<Pkt6Ptr>(Option::V6, query, Pkt6Ptr());
107 } catch (const std::exception& ex) {
109 .arg(query->getLabel())
110 .arg(ex.what());
111 }
112
113 return (0);
114}
115
127 if (status == CalloutHandle::NEXT_STEP_DROP) {
128 return (0);
129 }
130
131 // Sanity.
132 if (!impl) {
133 return (0);
134 }
135
136 // Get the parameters.
137 Pkt4Ptr query;
138 Pkt4Ptr response;
139 handle.getArgument("query4", query);
140 handle.getArgument("response4", response);
141
142 if (status == CalloutHandle::NEXT_STEP_SKIP) {
143 isc_throw(InvalidOperation, "packet pack already handled");
144 }
145 if (!query || !response) {
146 return (0);
147 }
148
149 try {
150 impl->process<Pkt4Ptr>(Option::V4, query, response);
151 } catch (const std::exception& ex) {
153 .arg(query->getLabel())
154 .arg(ex.what());
155 }
156
157 return (0);
158}
159
171 if (status == CalloutHandle::NEXT_STEP_DROP) {
172 return (0);
173 }
174
175 // Sanity.
176 if (!impl) {
177 return (0);
178 }
179
180 // Get the parameters.
181 Pkt6Ptr query;
182 Pkt6Ptr response;
183 handle.getArgument("query6", query);
184 handle.getArgument("response6", response);
185
186 if (status == CalloutHandle::NEXT_STEP_SKIP) {
187 isc_throw(InvalidOperation, "packet pack already handled");
188 }
189 if (!query || !response) {
190 return (0);
191 }
192
193 try {
194 impl->process<Pkt6Ptr>(Option::V6, query, response);
195 } catch (const std::exception& ex) {
197 .arg(query->getLabel())
198 .arg(ex.what());
199 }
200
201 return (0);
202}
203
208int load(LibraryHandle& handle) {
209 try {
210 // Make the hook library not loadable by d2.
211 uint16_t family = CfgMgr::instance().getFamily();
212 const std::string& proc_name = Daemon::getProcName();
213 if (family == AF_INET) {
214 if (proc_name != "kea-dhcp4") {
215 isc_throw(isc::Unexpected, "Bad process name: " << proc_name
216 << ", expected kea-dhcp4");
217 }
218 } else {
219 if (proc_name != "kea-dhcp6") {
220 isc_throw(isc::Unexpected, "Bad process name: " << proc_name
221 << ", expected kea-dhcp6");
222 }
223 }
224
225 impl.reset(new FlexOptionImpl());
226 ConstElementPtr options = handle.getParameter("options");
227 impl->configure(options);
228 } catch (const std::exception& ex) {
230 .arg(ex.what());
231 return (1);
232 }
233
234 return (0);
235}
236
240int unload() {
241 impl.reset();
243 return (0);
244}
245
250 return (1);
251}
252
253} // end extern "C"
CalloutNextStep
Specifies allowed next steps.
@ NEXT_STEP_DROP
drop the packet
@ NEXT_STEP_SKIP
skip the next processing step
A generic exception that is thrown if a function is called in a prohibited way.
A generic exception that is thrown when an unexpected error condition occurs.
uint16_t getFamily() const
Returns address family.
Definition cfgmgr.h:246
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition cfgmgr.cc:29
Flex Option implementation.
Definition flex_option.h:37
Per-packet callout handle.
CalloutNextStep getStatus() const
Returns the next processing step.
void getArgument(const std::string &name, T &value) const
Get argument.
isc::data::ConstElementPtr getParameter(const std::string &name)
Returns configuration parameter for the library.
static std::string getProcName()
returns the process name This value is used as when forming the default PID file name
Definition daemon.cc:156
This file contains several functions and constants that are used for handling commands and responses ...
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
int multi_threading_compatible()
This function is called to retrieve the multi-threading compatibility.
int pkt6_send(CalloutHandle &handle)
This callout is called at the "pkt6_send" hook.
int pkt4_send(CalloutHandle &handle)
This callout is called at the "pkt4_send" hook.
int unload()
This function is called when the library is unloaded.
int pkt4_receive(CalloutHandle &handle)
This callout is called at the "pkt4_receive" hook.
int pkt6_receive(CalloutHandle &handle)
This callout is called at the "pkt6_receive" hook.
int load(LibraryHandle &handle)
This function is called when the library is loaded.
const isc::log::MessageID FLEX_OPTION_PROCESS_ERROR
const isc::log::MessageID FLEX_OPTION_LOAD_ERROR
const isc::log::MessageID FLEX_OPTION_UNLOAD
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition macros.h:32
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition macros.h:20
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:30
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
Definition pkt4.h:556
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
Definition pkt6.h:31
FlexOptionImplPtr impl
isc::log::Logger flex_option_logger("flex-option-hooks")
boost::shared_ptr< FlexOptionImpl > FlexOptionImplPtr
The type of shared pointers to Flex Option implementations.
Defines the logger used by the top-level component of kea-lfc.