1 /*#############################################################################
3 # IPFire.org - A linux based firewall #
4 # Copyright (C) 2023 IPFire Network Development Team #
6 # This program is free software: you can redistribute it and/or modify #
7 # it under the terms of the GNU General Public License as published by #
8 # the Free Software Foundation, either version 3 of the License, or #
9 # (at your option) any later version. #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
19 #############################################################################*/
28 #include <systemd/sd-bus.h>
29 #include <systemd/sd-daemon.h>
30 #include <systemd/sd-device.h>
31 #include <systemd/sd-event.h>
32 #include <systemd/sd-netlink.h>
42 #include "stats-collector.h"
47 // Increase the receive buffer to 128 MiB
48 #define RCVBUF_SIZE 128 * 1024 * 1024
67 sd_device_monitor
* devmon
;
79 sd_event_source
* stats_collector_event
;
82 static int __nw_daemon_terminate(sd_event_source
* source
, const struct signalfd_siginfo
* si
,
84 DEBUG("Received signal to terminate...\n");
86 return sd_event_exit(sd_event_source_get_event(source
), 0);
89 static int __nw_daemon_reload(sd_event_source
* source
, const struct signalfd_siginfo
* si
,
91 nw_daemon
* daemon
= (nw_daemon
*)daemon
;
93 DEBUG("Received signal to reload...\n");
96 nw_daemon_reload(daemon
);
105 static int nw_daemon_config_open(nw_daemon
* daemon
, const char* path
) {
108 // Open the configuration directory
109 r
= nw_configd_create(&daemon
->configd
, path
);
116 static int nw_daemon_parse_argv(nw_daemon
* daemon
, int argc
, char* argv
[]) {
122 static const struct option options
[] = {
123 { "config", required_argument
, NULL
, ARG_CONFIG
},
129 c
= getopt_long(argc
, argv
, "", options
, NULL
);
135 r
= nw_daemon_config_open(daemon
, optarg
);
140 // Abort on any unrecognised option
149 static int nw_daemon_setup_loop(nw_daemon
* daemon
) {
152 // Fetch a reference to the default event loop
153 r
= sd_event_default(&daemon
->loop
);
155 ERROR("Could not setup event loop: %s\n", strerror(-r
));
159 // Enable the watchdog
160 r
= sd_event_set_watchdog(daemon
->loop
, 1);
162 ERROR("Could not activate watchdog: %s\n", strerror(-r
));
166 // Listen for SIGTERM
167 r
= sd_event_add_signal(daemon
->loop
, NULL
, SIGTERM
|SD_EVENT_SIGNAL_PROCMASK
,
168 __nw_daemon_terminate
, daemon
);
170 ERROR("Could not register handling SIGTERM: %s\n", strerror(-r
));
175 r
= sd_event_add_signal(daemon
->loop
, NULL
, SIGINT
|SD_EVENT_SIGNAL_PROCMASK
,
176 __nw_daemon_terminate
, daemon
);
178 ERROR("Could not register handling SIGINT: %s\n", strerror(-r
));
183 r
= sd_event_add_signal(daemon
->loop
, NULL
, SIGHUP
|SD_EVENT_SIGNAL_PROCMASK
,
184 __nw_daemon_reload
, daemon
);
186 ERROR("Could not register handling SIGHUP: %s\n", strerror(-r
));
193 static int nw_daemon_load_config(nw_daemon
* daemon
) {
196 // If no configuration path has been opened yet, we will open something
197 if (!daemon
->configd
) {
198 r
= nw_daemon_config_open(daemon
, CONFIG_DIR
);
203 // Open the configuration file
204 return nw_configd_open_config(&daemon
->config
, daemon
->configd
, "settings");
207 static int nw_start_device_monitor(nw_daemon
* daemon
) {
210 const char* subsystems
[] = {
217 // Create a new connection to monitor any devices
218 r
= sd_device_monitor_new(&daemon
->devmon
);
220 ERROR("Could not inititalize the device monitor: %m\n");
224 // Increase the receive buffer
225 r
= sd_device_monitor_set_receive_buffer_size(daemon
->devmon
, RCVBUF_SIZE
);
227 ERROR("Could not increase buffer size for the device monitor: %m\n");
231 // Filter for events for all relevant subsystems
232 for (const char** subsystem
= subsystems
; *subsystem
; subsystem
++) {
233 r
= sd_device_monitor_filter_add_match_subsystem_devtype(
234 daemon
->devmon
, *subsystem
, NULL
);
236 ERROR("Could not add device monitor for the %s subsystem: %m\n", *subsystem
);
241 // Attach the device monitor to the event loop
242 r
= sd_device_monitor_attach_event(daemon
->devmon
, daemon
->loop
);
244 ERROR("Could not attach the device monitor to the event loop: %m\n");
248 // Start processing events...
249 r
= sd_device_monitor_start(daemon
->devmon
, nw_devmon_handle_uevent
, daemon
);
251 ERROR("Could not start the device monitor: %m\n");
258 static int nw_daemon_connect_rtnl(nw_daemon
* daemon
, int fd
) {
261 // Connect to Netlink
262 r
= sd_netlink_open(&daemon
->rtnl
);
264 ERROR("Could not connect to the kernel's netlink interface: %m\n");
268 // Increase the receive buffer
269 r
= sd_netlink_increase_rxbuf(daemon
->rtnl
, RCVBUF_SIZE
);
271 ERROR("Could not increase receive buffer for the netlink socket: %m\n");
275 // Connect it to the event loop
276 r
= sd_netlink_attach_event(daemon
->rtnl
, daemon
->loop
, 0);
278 ERROR("Could not connect the netlink socket to the event loop: %m\n");
282 // Register callback for new interfaces
283 r
= sd_netlink_add_match(daemon
->rtnl
, NULL
, RTM_NEWLINK
, nw_link_process
, NULL
,
284 daemon
, "networkd-RTM_NEWLINK");
286 ERROR("Could not register RTM_NEWLINK: %m\n");
290 // Register callback for deleted interfaces
291 r
= sd_netlink_add_match(daemon
->rtnl
, NULL
, RTM_DELLINK
, nw_link_process
, NULL
,
292 daemon
, "networkd-RTM_DELLINK");
294 ERROR("Could not register RTM_DELLINK: %m\n");
301 static int nw_daemon_enumerate_links(nw_daemon
* daemon
) {
304 // Create a new links container
305 r
= nw_links_create(&daemon
->links
, daemon
);
309 return nw_links_enumerate(daemon
->links
);
312 static int nw_daemon_enumerate_ports(nw_daemon
* daemon
) {
315 // Create a new ports container
316 r
= nw_ports_create(&daemon
->ports
, daemon
);
320 return nw_ports_enumerate(daemon
->ports
);
323 static int nw_daemon_enumerate_zones(nw_daemon
* daemon
) {
326 // Create a new zones container
327 r
= nw_zones_create(&daemon
->zones
, daemon
);
331 return nw_zones_enumerate(daemon
->zones
);
334 static int nw_daemon_enumerate(nw_daemon
* daemon
) {
338 r
= nw_daemon_enumerate_links(daemon
);
343 r
= nw_daemon_enumerate_ports(daemon
);
348 r
= nw_daemon_enumerate_zones(daemon
);
355 static int __nw_daemon_reconfigure(sd_event_source
* s
, void* data
) {
356 nw_daemon
* daemon
= (nw_daemon
*)data
;
359 DEBUG("Reconfiguring...\n");
361 // Reconfigure all zones
362 r
= nw_zones_reconfigure(daemon
->zones
);
366 // Reconfigure all ports
367 r
= nw_ports_reconfigure(daemon
->ports
);
374 static int nw_daemon_reconfigure(nw_daemon
* daemon
) {
377 r
= sd_event_add_defer(daemon
->loop
, NULL
, __nw_daemon_reconfigure
, daemon
);
379 ERROR("Could not schedule re-configuration task: %m\n");
386 static int nw_daemon_starts_stats_collector(nw_daemon
* daemon
) {
387 sd_event_source
* s
= NULL
;
390 // Register the stats collector main function
391 r
= sd_event_add_time_relative(daemon
->loop
, &s
, CLOCK_MONOTONIC
, 0, 0,
392 nw_stats_collector
, daemon
);
394 ERROR("Could not start the stats collector: %m\n");
398 // Keep calling the stats collector for forever
399 r
= sd_event_source_set_enabled(s
, SD_EVENT_ON
);
403 // Keep a reference to the event source
404 daemon
->stats_collector_event
= sd_event_source_ref(s
);
408 sd_event_source_unref(s
);
413 static int nw_daemon_setup(nw_daemon
* daemon
) {
416 // Read the configuration
417 r
= nw_daemon_load_config(daemon
);
421 // Setup the event loop
422 r
= nw_daemon_setup_loop(daemon
);
426 // Connect to the kernel's netlink interface
427 r
= nw_daemon_connect_rtnl(daemon
, 0);
431 // Connect to the system bus
432 r
= nw_bus_connect(&daemon
->bus
, daemon
->loop
, daemon
);
437 r
= nw_start_device_monitor(daemon
);
441 // Enumerate everything we need to know
442 r
= nw_daemon_enumerate(daemon
);
446 // (Re-)configure everything
447 r
= nw_daemon_reconfigure(daemon
);
451 // Start the stats collector
452 r
= nw_daemon_starts_stats_collector(daemon
);
459 int nw_daemon_create(nw_daemon
** daemon
, int argc
, char* argv
[]) {
462 nw_daemon
* d
= calloc(1, sizeof(*d
));
466 // Initialize reference counter
469 // Parse command line arguments
470 r
= nw_daemon_parse_argv(d
, argc
, argv
);
475 r
= nw_daemon_setup(d
);
490 static void nw_daemon_cleanup(nw_daemon
* daemon
) {
492 nw_ports_unref(daemon
->ports
);
494 nw_zones_unref(daemon
->zones
);
496 nw_links_unref(daemon
->links
);
498 nw_config_unref(daemon
->config
);
501 static void nw_daemon_free(nw_daemon
* daemon
) {
502 // Cleanup common objects
503 nw_daemon_cleanup(daemon
);
506 nw_configd_unref(daemon
->configd
);
507 if (daemon
->stats_collector_event
)
508 sd_event_source_unref(daemon
->stats_collector_event
);
510 sd_bus_unref(daemon
->bus
);
512 sd_event_unref(daemon
->loop
);
517 nw_daemon
* nw_daemon_ref(nw_daemon
* daemon
) {
523 nw_daemon
* nw_daemon_unref(nw_daemon
* daemon
) {
524 if (--daemon
->nrefs
> 0)
527 nw_daemon_free(daemon
);
532 This function contains the main loop of the daemon...
534 int nw_daemon_run(nw_daemon
* daemon
) {
537 // We are now ready to process any requests
538 sd_notify(0, "READY=1\n" "STATUS=Processing requests...");
540 // Launch the event loop
541 r
= sd_event_loop(daemon
->loop
);
543 ERROR("Could not run the event loop: %s\n", strerror(-r
));
547 // Let systemd know that we are shutting down
548 sd_notify(0, "STOPPING=1\n" "STATUS=Shutting down...");
550 // Save the configuration
551 r
= nw_daemon_save(daemon
);
555 // Cleanup everything
556 nw_daemon_cleanup(daemon
);
561 sd_notifyf(0, "ERRNO=%i", -r
);
563 // Cleanup everything
564 nw_daemon_cleanup(daemon
);
569 int nw_daemon_reload(nw_daemon
* daemon
) {
570 DEBUG("Reloading daemon...\n");
578 Saves the configuration to disk
580 int nw_daemon_save(nw_daemon
* daemon
) {
583 DEBUG("Saving configuration...\n");
587 r
= nw_config_write(daemon
->config
, f
);
593 r
= nw_ports_save(daemon
->ports
);
598 r
= nw_zones_save(daemon
->zones
);
605 nw_configd
* nw_daemon_configd(nw_daemon
* daemon
, const char* path
) {
606 if (!daemon
->configd
)
610 return nw_configd_descend(daemon
->configd
, path
);
612 return nw_configd_ref(daemon
->configd
);
618 sd_bus
* nw_daemon_get_bus(nw_daemon
* daemon
) {
625 sd_netlink
* nw_daemon_get_rtnl(nw_daemon
* daemon
) {
632 nw_links
* nw_daemon_links(nw_daemon
* daemon
) {
633 return nw_links_ref(daemon
->links
);
636 void nw_daemon_drop_link(nw_daemon
* daemon
, nw_link
* link
) {
640 nw_links_drop_link(daemon
->links
, link
);
643 nw_link
* nw_daemon_get_link_by_ifindex(nw_daemon
* daemon
, int ifindex
) {
647 return nw_links_get_by_ifindex(daemon
->links
, ifindex
);
650 nw_link
* nw_daemon_get_link_by_name(nw_daemon
* daemon
, const char* name
) {
654 return nw_links_get_by_name(daemon
->links
, name
);
660 nw_ports
* nw_daemon_ports(nw_daemon
* daemon
) {
661 return nw_ports_ref(daemon
->ports
);
664 int nw_daemon_ports_walk(nw_daemon
* daemon
, nw_ports_walk_callback callback
, void* data
) {
668 return nw_ports_walk(daemon
->ports
, callback
, data
);
671 nw_port
* nw_daemon_get_port_by_name(nw_daemon
* daemon
, const char* name
) {
675 return nw_ports_get_by_name(daemon
->ports
, name
);
682 nw_zones
* nw_daemon_zones(nw_daemon
* daemon
) {
683 return nw_zones_ref(daemon
->zones
);
686 int nw_daemon_zones_walk(nw_daemon
* daemon
, nw_zones_walk_callback callback
, void* data
) {
690 return nw_zones_walk(daemon
->zones
, callback
, data
);
693 nw_zone
* nw_daemon_get_zone_by_name(nw_daemon
* daemon
, const char* name
) {
697 return nw_zones_get_by_name(daemon
->zones
, name
);