From: Michael Tremer Date: Sun, 4 Jun 2023 14:54:58 +0000 (+0000) Subject: ports: Move VLAN stuff into its own file X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ff88697584a58e86b3abdad0b5017fda382f50e9;p=network.git ports: Move VLAN stuff into its own file Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index 15e9fa0a..aafa59c0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -334,6 +334,8 @@ dist_networkd_SOURCES = \ src/networkd/port-bus.h \ src/networkd/port-dummy.c \ src/networkd/port-dummy.h \ + src/networkd/port-vlan.c \ + src/networkd/port-vlan.h \ src/networkd/stats-collector.c \ src/networkd/stats-collector.h \ src/networkd/string.h \ diff --git a/src/networkd/port-vlan.c b/src/networkd/port-vlan.c new file mode 100644 index 00000000..c9581f68 --- /dev/null +++ b/src/networkd/port-vlan.c @@ -0,0 +1,150 @@ +/*############################################################################# +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2023 IPFire Network Development Team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#include "config.h" +#include "daemon.h" +#include "logging.h" +#include "port.h" +#include "port-vlan.h" +#include "string.h" + +static int nw_port_vlan_config_read(nw_port* port) { + int r; + + // VLAN ID + int id = nw_config_get_int(port->config, "VLAN_ID", NW_VLAN_ID_INVALID); + if (id) { + r = nw_port_set_vlan_id(port, id); + if (r) + return r; + } + + // Parent Port + const char* parent = nw_config_get(port->config, "VLAN_PARENT"); + if (parent) { + r = nw_string_set(port->vlan.__parent_name, parent); + if (r) + return r; + } + + return 0; +} + +static int nw_port_vlan_config_write(nw_port* port) { + int r; + + // VLAN ID + r = nw_config_set_int(port->config, "VLAN_ID", port->vlan.id); + if (r) + return r; + + // Parent Port + r = nw_config_set(port->config, "VLAN_PARENT", + (port->vlan.parent) ? nw_port_name(port->vlan.parent) : port->vlan.__parent_name); + if (r) + return r; + + return 0; +} + +nw_port_ops_t nw_port_ops_vlan = { + // Configuration + .config_read = nw_port_vlan_config_read, + .config_write = nw_port_vlan_config_write, +}; + +/* + VLAN +*/ +int nw_port_get_vlan_id(nw_port* port) { + int r; + + // Check type + r = nw_port_check_type(port, NW_PORT_VLAN); + if (r < 0) + return r; + + return port->vlan.id; +} + +int nw_port_set_vlan_id(nw_port* port, int id) { + int r; + + // Check type + r = nw_port_check_type(port, NW_PORT_VLAN); + if (r < 0) + return r; + + // Check if the VLAN ID is within range + if (id < NW_VLAN_ID_MIN || id > NW_VLAN_ID_MAX) + return -EINVAL; + + // Store the ID + port->vlan.id = id; + + DEBUG("Port %s: Set VLAN ID to %d\n", port->name, port->vlan.id); + + return 0; +} + +nw_port* nw_port_get_vlan_parent(nw_port* port) { + int r; + + // Check type + r = nw_port_check_type(port, NW_PORT_VLAN); + if (r < 0) + return NULL; + + // Try to find a reference to the parent if none exists + if (!port->vlan.parent && *port->vlan.__parent_name) + port->vlan.parent = nw_daemon_get_port_by_name(port->daemon, port->vlan.__parent_name); + + if (port->vlan.parent) + return nw_port_ref(port->vlan.parent); + + // No port found + return NULL; +} + +int nw_port_set_vlan_parent(nw_port* port, nw_port* parent) { + int r; + + // Check type + r = nw_port_check_type(port, NW_PORT_VLAN); + if (r < 0) + return r; + + // Reset the former parent name + nw_string_empty(port->vlan.__parent_name); + + // Dereference the former parent + if (port->vlan.parent) { + nw_port_unref(port->vlan.parent); + port->vlan.parent = NULL; + } + + // Store the new parent + if (parent) + port->vlan.parent = nw_port_ref(parent); + + DEBUG("Port %s: Set VLAN parent to %s\n", port->name, nw_port_name(port->vlan.parent)); + + return 0; +} diff --git a/src/networkd/port-vlan.h b/src/networkd/port-vlan.h new file mode 100644 index 00000000..2bacb24d --- /dev/null +++ b/src/networkd/port-vlan.h @@ -0,0 +1,36 @@ +/*############################################################################# +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2023 IPFire Network Development Team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#ifndef NETWORKD_PORT_VLAN_H +#define NETWORKD_PORT_VLAN_H + +#include "port.h" + +extern nw_port_ops_t nw_port_ops_vlan; + +// ID +int nw_port_get_vlan_id(nw_port* port); +int nw_port_set_vlan_id(nw_port* port, int id); + +// Parent Port +nw_port* nw_port_get_vlan_parent(nw_port* port); +int nw_port_set_vlan_parent(nw_port* port, nw_port* parent); + +#endif /* NETWORKD_PORT_VLAN_H */ diff --git a/src/networkd/port.c b/src/networkd/port.c index 6ba48757..b3b7d668 100644 --- a/src/networkd/port.c +++ b/src/networkd/port.c @@ -31,39 +31,10 @@ #include "logging.h" #include "port.h" #include "port-dummy.h" +#include "port-vlan.h" #include "stats-collector.h" #include "string.h" -struct nw_port { - nw_daemon* daemon; - int nrefs; - - // Link - nw_link* link; - - nw_port_type_t type; - char name[IF_NAMESIZE]; - - // Configuration - nw_config *config; - - // Common attributes - nw_address_t address; - - // Type Operations - nw_port_ops_t ops; - - // VLAN settings - struct nw_port_vlan { - nw_port* parent; - int id; - - // If the parent has not been read from the configuration we will - // save the name and try to find it later. - char __parent_name[IF_NAMESIZE]; - } vlan; -}; - static const struct nw_port_type_map { nw_port_type_t type; const char* name; @@ -143,28 +114,6 @@ static int nw_port_setup_common(nw_port* port) { return 0; } -static int nw_port_setup_vlan(nw_port* port) { - int r; - - // VLAN ID - int id = nw_config_get_int(port->config, "VLAN_ID", NW_VLAN_ID_INVALID); - if (id) { - r = nw_port_set_vlan_id(port, id); - if (r) - return r; - } - - // Parent Port - const char* parent = nw_config_get(port->config, "VLAN_PARENT"); - if (parent) { - r = nw_string_set(port->vlan.__parent_name, parent); - if (r) - return r; - } - - return 0; -} - static int nw_port_set_link(nw_port* port, nw_link* link) { // Do nothing if the same link is being re-assigned if (port->link == link) @@ -219,17 +168,10 @@ static int nw_port_setup(nw_port* port) { goto ERROR; // Call any custom initialization - switch (port->type) { - case NW_PORT_VLAN: - r = nw_port_setup_vlan(port); - if (r) - goto ERROR; - break; - - // These do not need any special initialization - case NW_PORT_DUMMY: - case NW_PORT_UNKNOWN: - break; + if (port->ops.config_read) { + r = port->ops.config_read(port); + if (r) + goto ERROR; } ERROR: @@ -261,6 +203,10 @@ int nw_port_create(nw_port** port, nw_daemon* daemon, nw_port_type_t type, const case NW_PORT_DUMMY: p->ops = nw_port_ops_dummy; break; + + case NW_PORT_VLAN: + p->ops = nw_port_ops_vlan; + break; } // Store the name @@ -379,40 +325,17 @@ int __nw_port_drop_port(nw_daemon* daemon, nw_port* port, void* data) { return 0; } -static int nw_port_save_vlan(nw_port* port) { - int r; - - // VLAN ID - r = nw_config_set_int(port->config, "VLAN_ID", port->vlan.id); - if (r) - return r; - - // Parent Port - r = nw_config_set(port->config, "VLAN_PARENT", - (port->vlan.parent) ? nw_port_name(port->vlan.parent) : port->vlan.__parent_name); - if (r) - return r; - - return 0; -} - int nw_port_save(nw_port* port) { int r; - switch (port->type) { - // VLAN - case NW_PORT_VLAN: - r = nw_port_save_vlan(port); - if (r) - goto ERROR; - break; - - // These types do not have any special settings - case NW_PORT_DUMMY: - case NW_PORT_UNKNOWN: - break; + // Call the custom handler + if (port->ops.config_write) { + r = port->ops.config_write(port); + if (r) + goto ERROR; } + // Write the configuration r = nw_config_write(port->config); if (r) return r; @@ -481,7 +404,20 @@ static int nw_port_is_disabled(nw_port* port) { } static int nw_port_create_link(nw_port* port) { - return 0; // XXX TODO + int r; + + // Fail if the function isn't set + if (!port->ops.create_link) { + errno = ENOTSUP; + return -errno; + } + + // Create the link + r = port->ops.create_link(port); + if (r) + ERROR("Could not create link %s: %m\n", port->name); + + return r; } int nw_port_reconfigure(nw_port* port) { @@ -545,89 +481,10 @@ int nw_port_update_stats(nw_port* port) { return 0; } -static int nw_port_check_type(nw_port* port, const nw_port_type_t type) { +int nw_port_check_type(nw_port* port, const nw_port_type_t type) { if (port->type == type) return 0; errno = ENOTSUP; return -errno; } - -/* - VLAN -*/ -int nw_port_get_vlan_id(nw_port* port) { - int r; - - // Check type - r = nw_port_check_type(port, NW_PORT_VLAN); - if (r < 0) - return r; - - return port->vlan.id; -} - -int nw_port_set_vlan_id(nw_port* port, int id) { - int r; - - // Check type - r = nw_port_check_type(port, NW_PORT_VLAN); - if (r < 0) - return r; - - // Check if the VLAN ID is within range - if (id < NW_VLAN_ID_MIN || id > NW_VLAN_ID_MAX) - return -EINVAL; - - // Store the ID - port->vlan.id = id; - - DEBUG("Port %s: Set VLAN ID to %d\n", port->name, port->vlan.id); - - return 0; -} - -nw_port* nw_port_get_vlan_parent(nw_port* port) { - int r; - - // Check type - r = nw_port_check_type(port, NW_PORT_VLAN); - if (r < 0) - return NULL; - - // Try to find a reference to the parent if none exists - if (!port->vlan.parent && *port->vlan.__parent_name) - port->vlan.parent = nw_daemon_get_port_by_name(port->daemon, port->vlan.__parent_name); - - if (port->vlan.parent) - return nw_port_ref(port->vlan.parent); - - // No port found - return NULL; -} - -int nw_port_set_vlan_parent(nw_port* port, nw_port* parent) { - int r; - - // Check type - r = nw_port_check_type(port, NW_PORT_VLAN); - if (r < 0) - return r; - - // Reset the former parent name - nw_string_empty(port->vlan.__parent_name); - - // Dereference the former parent - if (port->vlan.parent) { - nw_port_unref(port->vlan.parent); - port->vlan.parent = NULL; - } - - // Store the new parent - if (parent) - port->vlan.parent = nw_port_ref(parent); - - DEBUG("Port %s: Set VLAN parent to %s\n", port->name, nw_port_name(port->vlan.parent)); - - return 0; -} diff --git a/src/networkd/port.h b/src/networkd/port.h index 76df7a77..5253d694 100644 --- a/src/networkd/port.h +++ b/src/networkd/port.h @@ -21,6 +21,10 @@ #ifndef NETWORKD_PORT_H #define NETWORKD_PORT_H +#ifndef IF_NAMESIZE +#define IF_NAMESIZE 16 +#endif + #define PORT_CONFIG_DIR CONFIG_DIR "/ports" typedef enum nw_port_type { @@ -42,10 +46,44 @@ typedef struct nw_port nw_port; typedef struct nw_port_ops { // Configuration - int (*config_read)(nw_port* port, nw_config* config); - int (*config_write)(nw_port* port, nw_config* config); + int (*config_read)(nw_port* port); + int (*config_write)(nw_port* port); + + // Link + int (*create_link)(nw_port* port); + int (*destroy_link)(nw_port* port); } nw_port_ops_t; +struct nw_port { + nw_daemon* daemon; + int nrefs; + + // Link + nw_link* link; + + nw_port_type_t type; + char name[IF_NAMESIZE]; + + // Configuration + nw_config *config; + + // Common attributes + nw_address_t address; + + // Type Operations + nw_port_ops_t ops; + + // VLAN settings + struct nw_port_vlan { + nw_port* parent; + int id; + + // If the parent has not been read from the configuration we will + // save the name and try to find it later. + char __parent_name[IF_NAMESIZE]; + } vlan; +}; + int nw_port_create(nw_port** port, nw_daemon* daemon, nw_port_type_t type, const char* name); int nw_port_create_from_config(nw_port** port, nw_daemon* daemon, @@ -72,16 +110,11 @@ int nw_port_reconfigure(nw_port* port); int nw_port_has_carrier(nw_port* port); +int nw_port_check_type(nw_port* port, const nw_port_type_t type); + // Stats const struct rtnl_link_stats64* nw_port_get_stats64(nw_port* port); int __nw_port_update_stats(nw_daemon* daemon, nw_port* port, void* data); int nw_port_update_stats(nw_port* port); -// VLAN -int nw_port_get_vlan_id(nw_port* port); -int nw_port_set_vlan_id(nw_port* port, int id); - -nw_port* nw_port_get_vlan_parent(nw_port* port); -int nw_port_set_vlan_parent(nw_port* port, nw_port* parent); - #endif /* NETWORKD_PORT_H */ diff --git a/src/networkd/ports.h b/src/networkd/ports.h index 68ae532f..4e41f112 100644 --- a/src/networkd/ports.h +++ b/src/networkd/ports.h @@ -26,6 +26,7 @@ typedef struct nw_ports nw_ports; typedef int (*nw_ports_walk_callback)(nw_daemon* daemon, nw_port* port, void* data); #include "daemon.h" +#include "port.h" int nw_ports_create(nw_ports** ports, nw_daemon* daemon);