diff options
Diffstat (limited to 'src/hooks/dhcp/run_script/run_script_callouts.cc')
-rw-r--r-- | src/hooks/dhcp/run_script/run_script_callouts.cc | 431 |
1 files changed, 431 insertions, 0 deletions
diff --git a/src/hooks/dhcp/run_script/run_script_callouts.cc b/src/hooks/dhcp/run_script/run_script_callouts.cc new file mode 100644 index 0000000..d4f8421 --- /dev/null +++ b/src/hooks/dhcp/run_script/run_script_callouts.cc @@ -0,0 +1,431 @@ +// Copyright (C) 2021 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 +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <cc/command_interpreter.h> +#include <hooks/hooks.h> +#include <run_script.h> +#include <run_script_log.h> +#include <dhcp/option6_ia.h> +#include <dhcp/pkt4.h> +#include <dhcp/pkt6.h> +#include <dhcpsrv/lease.h> +#include <dhcpsrv/subnet.h> + +namespace isc { +namespace run_script { + +RunScriptImplPtr impl; + +} // namespace run_script +} // namespace isc + +using namespace isc; +using namespace isc::asiolink; +using namespace isc::data; +using namespace isc::dhcp; +using namespace isc::hooks; +using namespace isc::run_script; +using namespace isc::util; + +// Functions accessed by the hooks framework use C linkage to avoid the name +// mangling that accompanies use of the C++ compiler as well as to avoid +// issues related to namespaces. +extern "C" { + +/// @brief This function is called when the library is loaded. +/// +/// @param handle library handle +/// @return 0 when initialization is successful, 1 otherwise +int load(LibraryHandle& handle) { + try { + impl.reset(new RunScriptImpl()); + impl->configure(handle); + } catch (const std::exception& ex) { + LOG_ERROR(run_script_logger, RUN_SCRIPT_LOAD_ERROR) + .arg(ex.what()); + return (1); + } + + LOG_INFO(run_script_logger, RUN_SCRIPT_LOAD); + return (0); +} + +/// @brief This function is called when the library is unloaded. +/// +/// @return always 0. +int unload() { + impl.reset(); + RunScriptImpl::setIOService(IOServicePtr()); + LOG_INFO(run_script_logger, RUN_SCRIPT_UNLOAD); + return (0); +} + +/// @brief dhcp4_srv_configured callout implementation. +/// +/// @param handle callout handle. +int dhcp4_srv_configured(CalloutHandle& handle) { + try { + isc::asiolink::IOServicePtr io_service; + handle.getArgument("io_context", io_service); + RunScriptImpl::setIOService(io_service); + + } catch (const std::exception& ex) { + LOG_ERROR(run_script_logger, RUN_SCRIPT_LOAD_ERROR) + .arg(ex.what()); + return (1); + } + return (0); +} + +/// @brief dhcp6_srv_configured callout implementation. +/// +/// @param handle callout handle. +int dhcp6_srv_configured(CalloutHandle& handle) { + try { + isc::asiolink::IOServicePtr io_service; + handle.getArgument("io_context", io_service); + RunScriptImpl::setIOService(io_service); + + } catch (const std::exception& ex) { + LOG_ERROR(run_script_logger, RUN_SCRIPT_LOAD_ERROR) + .arg(ex.what()); + return (1); + } + return (0); +} + +/// @brief handle @ref lease4_renew hook and set environment parameters for the +/// script. +/// IN: query4 subnet4 clientid hwaddr lease4 +/// OUT: next_step +int lease4_renew(CalloutHandle& handle) { + CalloutHandle::CalloutNextStep status = handle.getStatus(); + if (status == CalloutHandle::NEXT_STEP_DROP || + status == CalloutHandle::NEXT_STEP_SKIP) { + return (0); + } + ProcessEnvVars vars; + Pkt4Ptr pkt4; + handle.getArgument("query4", pkt4); + RunScriptImpl::extractPkt4(vars, pkt4, "QUERY4"); + Subnet4Ptr subnet4; + handle.getArgument("subnet4", subnet4); + RunScriptImpl::extractSubnet4(vars, subnet4, "SUBNET4"); + ClientIdPtr clientid; + handle.getArgument("clientid", clientid); + RunScriptImpl::extractDUID(vars, clientid, "PKT4_CLIENT_ID"); + HWAddrPtr hwaddr; + handle.getArgument("hwaddr", hwaddr); + RunScriptImpl::extractHWAddr(vars, hwaddr, "PKT4_HWADDR"); + Lease4Ptr lease4; + handle.getArgument("lease4", lease4); + RunScriptImpl::extractLease4(vars, lease4, "LEASE4"); + ProcessArgs args; + args.push_back("lease4_renew"); + impl->runScript(args, vars); + return (0); +} + +/// @brief handle @ref lease4_expire hook and set environment parameters for the +/// script. +/// IN: lease4 remove_lease +/// OUT: next_step +int lease4_expire(CalloutHandle& handle) { + CalloutHandle::CalloutNextStep status = handle.getStatus(); + if (status == CalloutHandle::NEXT_STEP_DROP || + status == CalloutHandle::NEXT_STEP_SKIP) { + return (0); + } + ProcessEnvVars vars; + Lease4Ptr lease4; + handle.getArgument("lease4", lease4); + RunScriptImpl::extractLease4(vars, lease4, "LEASE4"); + bool remove_lease; + handle.getArgument("remove_lease", remove_lease); + RunScriptImpl::extractBoolean(vars, remove_lease, "REMOVE_LEASE"); + ProcessArgs args; + args.push_back("lease4_expire"); + impl->runScript(args, vars); + return (0); +} + +/// @brief handle @ref lease4_recover hook and set environment parameters for +/// the script. +/// IN: lease4 +/// OUT: next_step +int lease4_recover(CalloutHandle& handle) { + CalloutHandle::CalloutNextStep status = handle.getStatus(); + if (status == CalloutHandle::NEXT_STEP_DROP || + status == CalloutHandle::NEXT_STEP_SKIP) { + return (0); + } + ProcessEnvVars vars; + Lease4Ptr lease4; + handle.getArgument("lease4", lease4); + RunScriptImpl::extractLease4(vars, lease4, "LEASE4"); + ProcessArgs args; + args.push_back("lease4_recover"); + impl->runScript(args, vars); + return (0); +} + +/// @brief handle @ref leases4_committed hook and set environment parameters for +/// the script. +/// IN: query4 leases4 deleted_leases4 +/// OUT: next_step +int leases4_committed(CalloutHandle& handle) { + CalloutHandle::CalloutNextStep status = handle.getStatus(); + if (status == CalloutHandle::NEXT_STEP_DROP || + status == CalloutHandle::NEXT_STEP_SKIP) { + return (0); + } + ProcessEnvVars vars; + Pkt4Ptr pkt4; + handle.getArgument("query4", pkt4); + RunScriptImpl::extractPkt4(vars, pkt4, "QUERY4"); + Lease4CollectionPtr leases4; + handle.getArgument("leases4", leases4); + RunScriptImpl::extractLeases4(vars, leases4, "LEASES4"); + Lease4CollectionPtr deleted_leases4; + handle.getArgument("deleted_leases4", deleted_leases4); + RunScriptImpl::extractLeases4(vars, deleted_leases4, "DELETED_LEASES4"); + ProcessArgs args; + args.push_back("leases4_committed"); + impl->runScript(args, vars); + return (0); +} + +/// @brief handle @ref lease4_release hook and set environment parameters for +/// the script. +/// IN: query4 lease4 +/// OUT: next_step +int lease4_release(CalloutHandle& handle) { + CalloutHandle::CalloutNextStep status = handle.getStatus(); + if (status == CalloutHandle::NEXT_STEP_DROP || + status == CalloutHandle::NEXT_STEP_SKIP) { + return (0); + } + ProcessEnvVars vars; + Pkt4Ptr pkt4; + handle.getArgument("query4", pkt4); + RunScriptImpl::extractPkt4(vars, pkt4, "QUERY4"); + Lease4Ptr lease4; + handle.getArgument("lease4", lease4); + RunScriptImpl::extractLease4(vars, lease4, "LEASE4"); + ProcessArgs args; + args.push_back("lease4_release"); + impl->runScript(args, vars); + return (0); +} + +/// @brief handle @ref lease4_decline hook and set environment parameters for +/// the script. +/// IN: query4 lease4 +/// OUT: next_step +int lease4_decline(CalloutHandle& handle) { + CalloutHandle::CalloutNextStep status = handle.getStatus(); + if (status == CalloutHandle::NEXT_STEP_DROP || + status == CalloutHandle::NEXT_STEP_SKIP) { + return (0); + } + ProcessEnvVars vars; + Pkt4Ptr pkt4; + handle.getArgument("query4", pkt4); + RunScriptImpl::extractPkt4(vars, pkt4, "QUERY4"); + Lease4Ptr lease4; + handle.getArgument("lease4", lease4); + RunScriptImpl::extractLease4(vars, lease4, "LEASE4"); + ProcessArgs args; + args.push_back("lease4_decline"); + impl->runScript(args, vars); + return (0); +} + +/// @brief handle @ref lease6_renew hook and set environment parameters for the +/// script. +/// IN: query6 lease6 ia_na/ia_pd +/// OUT: next_step +int lease6_renew(CalloutHandle& handle) { + CalloutHandle::CalloutNextStep status = handle.getStatus(); + if (status == CalloutHandle::NEXT_STEP_DROP || + status == CalloutHandle::NEXT_STEP_SKIP) { + return (0); + } + ProcessEnvVars vars; + Pkt6Ptr pkt6; + handle.getArgument("query6", pkt6); + RunScriptImpl::extractPkt6(vars, pkt6, "QUERY6"); + Lease6Ptr lease6; + handle.getArgument("lease6", lease6); + RunScriptImpl::extractLease6(vars, lease6, "LEASE6"); + Option6IAPtr option6IA; + if (lease6->type_ == Lease::TYPE_NA) { + handle.getArgument("ia_na", option6IA); + } else { + handle.getArgument("ia_pd", option6IA); + } + RunScriptImpl::extractOptionIA(vars, option6IA, "PKT6_IA"); + ProcessArgs args; + args.push_back("lease6_renew"); + impl->runScript(args, vars); + return (0); +} + +/// @brief handle @ref lease6_rebind hook and set environment parameters for the +/// script. +/// IN: query6 lease6 ia_na/ia_pd +/// OUT: next_step +int lease6_rebind(CalloutHandle& handle) { + CalloutHandle::CalloutNextStep status = handle.getStatus(); + if (status == CalloutHandle::NEXT_STEP_DROP || + status == CalloutHandle::NEXT_STEP_SKIP) { + return (0); + } + ProcessEnvVars vars; + Pkt6Ptr pkt6; + handle.getArgument("query6", pkt6); + RunScriptImpl::extractPkt6(vars, pkt6, "QUERY6"); + Lease6Ptr lease6; + handle.getArgument("lease6", lease6); + RunScriptImpl::extractLease6(vars, lease6, "LEASE6"); + Option6IAPtr option6IA; + if (lease6->type_ == Lease::TYPE_NA) { + handle.getArgument("ia_na", option6IA); + } else { + handle.getArgument("ia_pd", option6IA); + } + RunScriptImpl::extractOptionIA(vars, option6IA, "PKT6_IA"); + ProcessArgs args; + args.push_back("lease6_rebind"); + impl->runScript(args, vars); + return (0); +} + +/// @brief handle @ref lease6_expire hook and set environment parameters for the +/// script. +/// IN: lease6 remove_lease +/// OUT: next_step +int lease6_expire(CalloutHandle& handle) { + CalloutHandle::CalloutNextStep status = handle.getStatus(); + if (status == CalloutHandle::NEXT_STEP_DROP || + status == CalloutHandle::NEXT_STEP_SKIP) { + return (0); + } + ProcessEnvVars vars; + Lease6Ptr lease6; + handle.getArgument("lease6", lease6); + RunScriptImpl::extractLease6(vars, lease6, "LEASE6"); + bool remove_lease; + handle.getArgument("remove_lease", remove_lease); + RunScriptImpl::extractBoolean(vars, remove_lease, "REMOVE_LEASE"); + ProcessArgs args; + args.push_back("lease6_expire"); + impl->runScript(args, vars); + return (0); +} + +/// @brief handle @ref lease6_recover hook and set environment parameters for +/// the script. +/// IN: lease6 +/// OUT: next_step +int lease6_recover(CalloutHandle& handle) { + CalloutHandle::CalloutNextStep status = handle.getStatus(); + if (status == CalloutHandle::NEXT_STEP_DROP || + status == CalloutHandle::NEXT_STEP_SKIP) { + return (0); + } + ProcessEnvVars vars; + Lease6Ptr lease6; + handle.getArgument("lease6", lease6); + RunScriptImpl::extractLease6(vars, lease6, "LEASE6"); + ProcessArgs args; + args.push_back("lease6_recover"); + impl->runScript(args, vars); + return (0); +} + +/// @brief handle @ref leases6_committed hook and set environment parameters for +/// the script. +/// IN: query6 leases6 deleted_leases6 +/// OUT: next_step +int leases6_committed(CalloutHandle& handle) { + CalloutHandle::CalloutNextStep status = handle.getStatus(); + if (status == CalloutHandle::NEXT_STEP_DROP || + status == CalloutHandle::NEXT_STEP_SKIP) { + return (0); + } + ProcessEnvVars vars; + Pkt6Ptr pkt6; + handle.getArgument("query6", pkt6); + RunScriptImpl::extractPkt6(vars, pkt6, "QUERY6"); + Lease6CollectionPtr leases6; + handle.getArgument("leases6", leases6); + RunScriptImpl::extractLeases6(vars, leases6, "LEASES6"); + Lease6CollectionPtr deleted_leases6; + handle.getArgument("deleted_leases6", deleted_leases6); + RunScriptImpl::extractLeases6(vars, deleted_leases6, "DELETED_LEASES6"); + ProcessArgs args; + args.push_back("leases6_committed"); + impl->runScript(args, vars); + return (0); +} + +/// @brief handle @ref lease6_release hook and set environment parameters for +/// the script. +/// IN: query6 lease6 +/// OUT: next_step +int lease6_release(CalloutHandle& handle) { + CalloutHandle::CalloutNextStep status = handle.getStatus(); + if (status == CalloutHandle::NEXT_STEP_DROP || + status == CalloutHandle::NEXT_STEP_SKIP) { + return (0); + } + ProcessEnvVars vars; + Pkt6Ptr pkt6; + handle.getArgument("query6", pkt6); + RunScriptImpl::extractPkt6(vars, pkt6, "QUERY6"); + Lease6Ptr lease6; + handle.getArgument("lease6", lease6); + RunScriptImpl::extractLease6(vars, lease6, "LEASE6"); + ProcessArgs args; + args.push_back("lease6_release"); + impl->runScript(args, vars); + return (0); +} + +/// @brief handle @ref lease6_decline hook and set environment parameters for +/// the script. +/// IN: query6 lease6 +/// OUT: next_step +int lease6_decline(CalloutHandle& handle) { + CalloutHandle::CalloutNextStep status = handle.getStatus(); + if (status == CalloutHandle::NEXT_STEP_DROP || + status == CalloutHandle::NEXT_STEP_SKIP) { + return (0); + } + ProcessEnvVars vars; + Pkt6Ptr pkt6; + handle.getArgument("query6", pkt6); + RunScriptImpl::extractPkt6(vars, pkt6, "QUERY6"); + Lease6Ptr lease6; + handle.getArgument("lease6", lease6); + RunScriptImpl::extractLease6(vars, lease6, "LEASE6"); + ProcessArgs args; + args.push_back("lease6_decline"); + impl->runScript(args, vars); + return (0); +} + +/// @brief This function is called to retrieve the multi-threading compatibility. +/// +/// @return 1 which means compatible with multi-threading. +int multi_threading_compatible() { + return (1); +} + +} // end extern "C" |