Kea 3.1.1
subnet_cmds_callouts.cc
Go to the documentation of this file.
1// Copyright (C) 2017-2025 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
8// Functions accessed by the hooks framework use C linkage to avoid the name
9// mangling that accompanies use of the C++ compiler as well as to avoid
10// issues related to namespaces.
11
12#include <config.h>
13
14#include <subnet_cmds.h>
15#include <subnet_cmds_log.h>
17#include <hooks/hooks.h>
18#include <dhcpsrv/cfgmgr.h>
19#include <process/daemon.h>
20
21using namespace isc::config;
22using namespace isc::data;
23using namespace isc::dhcp;
24using namespace isc::hooks;
25using namespace isc::process;
26using namespace isc::subnet_cmds;
27
28extern "C" {
29
37 ConstElementPtr response;
38
39 try {
41 response = subnet_cmds.getSubnet4List();
42
43 } catch (const std::exception& ex) {
45 .arg(ex.what());
46 }
47
48 handle.setArgument("response", response);
49
50 return (0);
51}
52
60 ConstElementPtr response;
61
62 try {
64 response = subnet_cmds.getSubnet6List();
65
66 } catch (const std::exception& ex) {
68 .arg(ex.what());
69 }
70
71 handle.setArgument("response", response);
72
73 return (0);
74}
75
83 ConstElementPtr response;
84
85 try {
86 ConstElementPtr command;
87 handle.getArgument("command", command);
88 ConstElementPtr args;
89 static_cast<void>(parseCommand(args, command));
90
92 response = subnet_cmds.getSubnet4(args);
93
94 } catch (const std::exception& ex) {
95 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
96
98 .arg(ex.what());
99 }
100
101 handle.setArgument("response", response);
102
103 return (0);
104}
105
113 ConstElementPtr response;
114
115 try {
116 ConstElementPtr command;
117 handle.getArgument("command", command);
118 ConstElementPtr args;
119 static_cast<void>(parseCommand(args, command));
120
122 response = subnet_cmds.getSubnet6(args);
123
124 } catch (const std::exception& ex) {
125 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
126
128 .arg(ex.what());
129 }
130
131 handle.setArgument("response", response);
132
133 return (0);
134}
135
143 ConstElementPtr response;
144
145 try {
146 ConstElementPtr command;
147 handle.getArgument("command", command);
148 ConstElementPtr args;
149 static_cast<void>(parseCommand(args, command));
150
152 response = subnet_cmds.addSubnet4(args);
153
154 } catch (const std::exception& ex) {
155 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
156
158 .arg(ex.what());
159 }
160
161 handle.setArgument("response", response);
162
163 return (0);
164}
165
173 ConstElementPtr response;
174
175 try {
176 ConstElementPtr command;
177 handle.getArgument("command", command);
178 ConstElementPtr args;
179 static_cast<void>(parseCommand(args, command));
180
182 response = subnet_cmds.addSubnet6(args);
183
184 } catch (const std::exception& ex) {
185 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
186
188 .arg(ex.what());
189 }
190
191 handle.setArgument("response", response);
192
193 return (0);
194}
195
203 ConstElementPtr response;
204
205 try {
206 ConstElementPtr command;
207 handle.getArgument("command", command);
208 ConstElementPtr args;
209 static_cast<void>(parseCommand(args, command));
210
212 response = subnet_cmds.updateSubnet4(args);
213
214 } catch (const std::exception& ex) {
215 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
216
218 .arg(ex.what());
219 }
220
221 handle.setArgument("response", response);
222
223 return (0);
224}
225
233 ConstElementPtr response;
234
235 try {
236 ConstElementPtr command;
237 handle.getArgument("command", command);
238 ConstElementPtr args;
239 static_cast<void>(parseCommand(args, command));
240
242 response = subnet_cmds.updateSubnet6(args);
243
244 } catch (const std::exception& ex) {
245 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
246
248 .arg(ex.what());
249 }
250
251 handle.setArgument("response", response);
252
253 return (0);
254}
255
263 ConstElementPtr response;
264
265 try {
266 ConstElementPtr command;
267 handle.getArgument("command", command);
268 ConstElementPtr args;
269 static_cast<void>(parseCommand(args, command));
270
272 response = subnet_cmds.delSubnet4(args);
273
274 } catch (const std::exception& ex) {
275 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
276
278 .arg(ex.what());
279 }
280
281 handle.setArgument("response", response);
282
283 return (0);
284}
285
293 ConstElementPtr response;
294
295 try {
296 ConstElementPtr command;
297 handle.getArgument("command", command);
298 ConstElementPtr args;
299 static_cast<void>(parseCommand(args, command));
300
302 response = subnet_cmds.delSubnet6(args);
303
304 } catch (const std::exception& ex) {
305 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
306
308 .arg(ex.what());
309 }
310
311 handle.setArgument("response", response);
312
313 return (0);
314}
315
323 ConstElementPtr response;
324
325 try {
326 ConstElementPtr command;
327 handle.getArgument("command", command);
328 ConstElementPtr args;
329 static_cast<void>(parseCommand(args, command));
330
332 response = subnet_cmds.addSubnet4Delta(args);
333
334 } catch (const std::exception& ex) {
335 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
336
338 .arg(ex.what());
339 }
340
341 handle.setArgument("response", response);
342
343 return (0);
344}
345
353 ConstElementPtr response;
354
355 try {
356 ConstElementPtr command;
357 handle.getArgument("command", command);
358 ConstElementPtr args;
359 static_cast<void>(parseCommand(args, command));
360
362 response = subnet_cmds.addSubnet6Delta(args);
363
364 } catch (const std::exception& ex) {
365 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
366
368 .arg(ex.what());
369 }
370
371 handle.setArgument("response", response);
372
373 return (0);
374}
375
383 ConstElementPtr response;
384
385 try {
386 ConstElementPtr command;
387 handle.getArgument("command", command);
388 ConstElementPtr args;
389 static_cast<void>(parseCommand(args, command));
390
392 response = subnet_cmds.delSubnet4Delta(args);
393
394 } catch (const std::exception& ex) {
395 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
396
398 .arg(ex.what());
399 }
400
401 handle.setArgument("response", response);
402
403 return (0);
404}
405
413 ConstElementPtr response;
414
415 try {
416 ConstElementPtr command;
417 handle.getArgument("command", command);
418 ConstElementPtr args;
419 static_cast<void>(parseCommand(args, command));
420
422 response = subnet_cmds.delSubnet6Delta(args);
423
424 } catch (const std::exception& ex) {
425 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
426
428 .arg(ex.what());
429 }
430
431 handle.setArgument("response", response);
432
433 return (0);
434}
435
436// -----------------------------------------------------------------------------
437// --- SHARED NETWORKS ---------------------------------------------------------
438// -----------------------------------------------------------------------------
439
447 ConstElementPtr response;
448
449 try {
451 response = subnet_cmds.getNetwork4List();
452
453 } catch (const std::exception& ex) {
455 .arg(ex.what());
456 }
457
458 handle.setArgument("response", response);
459
460 return (0);
461}
462
470 ConstElementPtr response;
471
472 try {
474 response = subnet_cmds.getNetwork6List();
475
476 } catch (const std::exception& ex) {
478 .arg(ex.what());
479 }
480
481 handle.setArgument("response", response);
482
483 return (0);
484}
485
493 ConstElementPtr response;
494
495 try {
496 ConstElementPtr command;
497 handle.getArgument("command", command);
498 ConstElementPtr args;
499 static_cast<void>(parseCommand(args, command));
500
502 response = subnet_cmds.getNetwork4(args);
503
504 } catch (const std::exception& ex) {
505 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
506
508 .arg(ex.what());
509 }
510
511 handle.setArgument("response", response);
512
513 return (0);
514}
515
523 ConstElementPtr response;
524
525 try {
526 ConstElementPtr command;
527 handle.getArgument("command", command);
528 ConstElementPtr args;
529 static_cast<void>(parseCommand(args, command));
530
532 response = subnet_cmds.getNetwork6(args);
533
534 } catch (const std::exception& ex) {
535 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
536
538 .arg(ex.what());
539 }
540
541 handle.setArgument("response", response);
542
543 return (0);
544}
545
553 ConstElementPtr response;
554
555 try {
556 ConstElementPtr command;
557 handle.getArgument("command", command);
558 ConstElementPtr args;
559 static_cast<void>(parseCommand(args, command));
560
562 response = subnet_cmds.addNetwork4(args);
563
564 } catch (const std::exception& ex) {
565 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
566
568 .arg(ex.what());
569 }
570
571 handle.setArgument("response", response);
572
573 return (0);
574}
575
583 ConstElementPtr response;
584
585 try {
586 ConstElementPtr command;
587 handle.getArgument("command", command);
588 ConstElementPtr args;
589 static_cast<void>(parseCommand(args, command));
590
592 response = subnet_cmds.addNetwork6(args);
593
594 } catch (const std::exception& ex) {
595 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
596
598 .arg(ex.what());
599 }
600
601 handle.setArgument("response", response);
602
603 return (0);
604}
605
613 ConstElementPtr response;
614
615 try {
616 ConstElementPtr command;
617 handle.getArgument("command", command);
618 ConstElementPtr args;
619 static_cast<void>(parseCommand(args, command));
620
622 response = subnet_cmds.delNetwork4(args);
623
624 } catch (const std::exception& ex) {
625 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
626
628 .arg(ex.what());
629 }
630
631 handle.setArgument("response", response);
632
633 return (0);
634}
635
643 ConstElementPtr response;
644
645 try {
646 ConstElementPtr command;
647 handle.getArgument("command", command);
648 ConstElementPtr args;
649 static_cast<void>(parseCommand(args, command));
650
652 response = subnet_cmds.delNetwork6(args);
653
654 } catch (const std::exception& ex) {
655 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
656
658 .arg(ex.what());
659 }
660
661 handle.setArgument("response", response);
662
663 return (0);
664}
665
673 ConstElementPtr response;
674
675 try {
676 ConstElementPtr command;
677 handle.getArgument("command", command);
678 ConstElementPtr args;
679 static_cast<void>(parseCommand(args, command));
680
682 response = subnet_cmds.addNetwork4Subnet(args);
683
684 } catch (const std::exception& ex) {
685 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
686
688 .arg(ex.what());
689 }
690
691 handle.setArgument("response", response);
692
693 return (0);
694}
695
703 ConstElementPtr response;
704
705 try {
706 ConstElementPtr command;
707 handle.getArgument("command", command);
708 ConstElementPtr args;
709 static_cast<void>(parseCommand(args, command));
710
712 response = subnet_cmds.addNetwork6Subnet(args);
713
714 } catch (const std::exception& ex) {
715 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
716
718 .arg(ex.what());
719 }
720
721 handle.setArgument("response", response);
722
723 return (0);
724}
725
733 ConstElementPtr response;
734
735 try {
736 ConstElementPtr command;
737 handle.getArgument("command", command);
738 ConstElementPtr args;
739 static_cast<void>(parseCommand(args, command));
740
742 response = subnet_cmds.delNetwork4Subnet(args);
743
744 } catch (const std::exception& ex) {
745 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
746
748 .arg(ex.what());
749 }
750
751 handle.setArgument("response", response);
752
753 return (0);
754}
755
763 ConstElementPtr response;
764
765 try {
766 ConstElementPtr command;
767 handle.getArgument("command", command);
768 ConstElementPtr args;
769 static_cast<void>(parseCommand(args, command));
770
772 response = subnet_cmds.delNetwork6Subnet(args);
773
774 } catch (const std::exception& ex) {
775 response = createAnswer(CONTROL_RESULT_ERROR, ex.what());
776
778 .arg(ex.what());
779 }
780
781 handle.setArgument("response", response);
782
783 return (0);
784}
785
790int load(LibraryHandle& handle) {
791 try {
792 // Make the hook library not loadable by d2 or ca.
793 uint16_t family = CfgMgr::instance().getFamily();
794 const std::string& proc_name = Daemon::getProcName();
795 if (family == AF_INET) {
796 if (proc_name != "kea-dhcp4") {
797 isc_throw(isc::Unexpected, "Bad process name: " << proc_name
798 << ", expected kea-dhcp4");
799 }
800 } else {
801 if (proc_name != "kea-dhcp6") {
802 isc_throw(isc::Unexpected, "Bad process name: " << proc_name
803 << ", expected kea-dhcp6");
804 }
805 }
806
807 // Register commands for handling subnets.
808 handle.registerCommandCallout("subnet4-list", subnet4_list);
809 handle.registerCommandCallout("subnet6-list", subnet6_list);
810 handle.registerCommandCallout("subnet4-get", subnet4_get);
811 handle.registerCommandCallout("subnet6-get", subnet6_get);
812 handle.registerCommandCallout("subnet4-add", subnet4_add);
813 handle.registerCommandCallout("subnet6-add", subnet6_add);
814 handle.registerCommandCallout("subnet4-update", subnet4_update);
815 handle.registerCommandCallout("subnet6-update", subnet6_update);
816 handle.registerCommandCallout("subnet4-del", subnet4_del);
817 handle.registerCommandCallout("subnet6-del", subnet6_del);
818 handle.registerCommandCallout("subnet4-delta-add", subnet4_delta_add);
819 handle.registerCommandCallout("subnet6-delta-add", subnet6_delta_add);
820 handle.registerCommandCallout("subnet4-delta-del", subnet4_delta_del);
821 handle.registerCommandCallout("subnet6-delta-del", subnet6_delta_del);
822
823 // Register commands for handling shared networks
824 handle.registerCommandCallout("network4-list", network4_list);
825 handle.registerCommandCallout("network6-list", network6_list);
826 handle.registerCommandCallout("network4-get", network4_get);
827 handle.registerCommandCallout("network6-get", network6_get);
828 handle.registerCommandCallout("network4-add", network4_add);
829 handle.registerCommandCallout("network6-add", network6_add);
830 handle.registerCommandCallout("network4-del", network4_del);
831 handle.registerCommandCallout("network6-del", network6_del);
832 handle.registerCommandCallout("network4-subnet-add",
834 handle.registerCommandCallout("network6-subnet-add",
836 handle.registerCommandCallout("network4-subnet-del",
838 handle.registerCommandCallout("network6-subnet-del",
840 } catch (const std::exception& ex) {
842 .arg(ex.what());
843 return (1);
844 }
845
846
848 return (0);
849}
850
854int unload() {
856 return (0);
857}
858
863 return (1);
864}
865
866} // end extern "C"
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
Per-packet callout handle.
void getArgument(const std::string &name, T &value) const
Get argument.
void setArgument(const std::string &name, T value)
Set argument.
void registerCommandCallout(const std::string &command_name, CalloutPtr callout)
Register control command handler.
static std::string getProcName()
returns the process name This value is used as when forming the default PID file name
Definition daemon.cc:151
Implements the logic for processing commands pertaining to subnets manipulation.
Definition subnet_cmds.h:25
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.
#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
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
std::string parseCommand(ConstElementPtr &arg, ConstElementPtr command)
Parses the given command into a string containing the actual command and an ElementPtr containing the...
ConstElementPtr createAnswer()
Creates a standard config/command level success answer message (i.e.
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:29
const isc::log::MessageID SUBNET_CMDS_NETWORK6_SUBNET_ADD_FAILED
const isc::log::MessageID SUBNET_CMDS_SUBNET6_DELTA_DEL_FAILED
const isc::log::MessageID SUBNET_CMDS_SUBNET6_DEL_FAILED
const isc::log::MessageID SUBNET_CMDS_NETWORK6_DEL_FAILED
const isc::log::MessageID SUBNET_CMDS_NETWORK4_SUBNET_ADD_FAILED
const isc::log::MessageID SUBNET_CMDS_SUBNET4_GET_FAILED
const isc::log::MessageID SUBNET_CMDS_SUBNET4_DELTA_ADD_FAILED
const isc::log::MessageID SUBNET_CMDS_SUBNET4_DELTA_DEL_FAILED
const isc::log::MessageID SUBNET_CMDS_NETWORK4_SUBNET_DEL_FAILED
const isc::log::MessageID SUBNET_CMDS_SUBNET4_ADD_FAILED
const isc::log::MessageID SUBNET_CMDS_NETWORK4_GET_FAILED
const isc::log::MessageID SUBNET_CMDS_NETWORK6_SUBNET_DEL_FAILED
const isc::log::MessageID SUBNET_CMDS_SUBNET6_ADD_FAILED
const isc::log::MessageID SUBNET_CMDS_SUBNET6_GET_FAILED
const isc::log::MessageID SUBNET_CMDS_SUBNET4_DEL_FAILED
const isc::log::MessageID SUBNET_CMDS_SUBNET6_DELTA_ADD_FAILED
const isc::log::MessageID SUBNET_CMDS_INIT_FAILED
const isc::log::MessageID SUBNET_CMDS_SUBNET4_LIST_FAILED
const isc::log::MessageID SUBNET_CMDS_NETWORK4_DEL_FAILED
const isc::log::MessageID SUBNET_CMDS_NETWORK4_LIST_FAILED
const isc::log::MessageID SUBNET_CMDS_INIT_OK
const isc::log::MessageID SUBNET_CMDS_NETWORK6_LIST_FAILED
const isc::log::MessageID SUBNET_CMDS_SUBNET6_LIST_FAILED
const isc::log::MessageID SUBNET_CMDS_DEINIT_OK
const isc::log::MessageID SUBNET_CMDS_NETWORK6_ADD_FAILED
isc::log::Logger subnet_cmds_logger("subnet-cmds-hooks")
const isc::log::MessageID SUBNET_CMDS_SUBNET6_UPDATE_FAILED
const isc::log::MessageID SUBNET_CMDS_NETWORK4_ADD_FAILED
const isc::log::MessageID SUBNET_CMDS_NETWORK6_GET_FAILED
const isc::log::MessageID SUBNET_CMDS_SUBNET4_UPDATE_FAILED
int network4_subnet_del(CalloutHandle &handle)
This is a command handler for 'network4-subnet-del' command.
int subnet6_list(CalloutHandle &handle)
This is a command handler for 'subnet6-list' command.
int network4_get(CalloutHandle &handle)
This is a command handler for 'network4-get' command.
int network6_subnet_add(CalloutHandle &handle)
This is a command handler for 'network6-subnet-add' command.
int subnet6_del(CalloutHandle &handle)
This is a command handler for 'subnet6-del' command.
int network4_list(CalloutHandle &handle)
This is a command handler for 'network4-list' command.
int subnet6_update(CalloutHandle &handle)
This is a command handler for 'subnet6-update' command.
int subnet6_delta_del(CalloutHandle &handle)
This is a command handler for 'subnet6-delta-del' command.
int subnet4_del(CalloutHandle &handle)
This is a command handler for 'subnet4-del' command.
int network6_del(CalloutHandle &handle)
This is a command handler for 'network6-del' command.
int multi_threading_compatible()
This function is called to retrieve the multi-threading compatibility.
int network4_add(CalloutHandle &handle)
This is a command handler for 'network4-add' command.
int network6_list(CalloutHandle &handle)
This is a command handler for 'network6-list' command.
int network6_get(CalloutHandle &handle)
This is a command handler for 'network4-get' command.
int network6_subnet_del(CalloutHandle &handle)
This is a command handler for 'network6-subnet-del' command.
int subnet6_delta_add(CalloutHandle &handle)
This is a command handler for 'subnet6-delta-add' command.
int subnet6_add(CalloutHandle &handle)
This is a command handler for 'subnet6-add' command.
int subnet4_delta_del(CalloutHandle &handle)
This is a command handler for 'subnet4-delta-del' command.
int subnet6_get(CalloutHandle &handle)
This is a command handler for 'subnet4-get' command.
int unload()
This function is called when the library is unloaded.
int network4_del(CalloutHandle &handle)
This is a command handler for 'network4-del' command.
int network4_subnet_add(CalloutHandle &handle)
This is a command handler for 'network4-subnet-add' command.
int subnet4_delta_add(CalloutHandle &handle)
This is a command handler for 'subnet4-delta-add' command.
int network6_add(CalloutHandle &handle)
This is a command handler for 'network6-add' command.
int subnet4_list(CalloutHandle &handle)
This is a command handler for 'subnet4-list' command.
int subnet4_update(CalloutHandle &handle)
This is a command handler for 'subnet4-update' command.
int subnet4_get(CalloutHandle &handle)
This is a command handler for 'subnet4-get' command.
int load(LibraryHandle &handle)
This function is called when the library is loaded.
int subnet4_add(CalloutHandle &handle)
This is a command handler for 'subnet4-add' command.