]> git.ipfire.org Git - network.git/commitdiff
ports: Move VLAN stuff into its own file
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 4 Jun 2023 14:54:58 +0000 (14:54 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 4 Jun 2023 14:54:58 +0000 (14:54 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/networkd/port-vlan.c [new file with mode: 0644]
src/networkd/port-vlan.h [new file with mode: 0644]
src/networkd/port.c
src/networkd/port.h
src/networkd/ports.h

index 15e9fa0ad08a6761ad2e267fda12c5625735e677..aafa59c0e2d9f29d274b79b7846e4dce467778c6 100644 (file)
@@ -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 (file)
index 0000000..c9581f6
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#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 (file)
index 0000000..2bacb24
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#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 */
index 6ba48757e13d4b130c22e5a7c1ebf4a7d0ccc6ab..b3b7d668914ba025ade34a98b6f10d2b5cb27335 100644 (file)
 #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;
-}
index 76df7a77e01dcfc328ad64e720c8b9dea861a4de..5253d694bca215823128020c59b2f7bd7ab7cb61 100644 (file)
 #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 */
index 68ae532ffb40cbb9278e37e396101ff68a00eb76..4e41f112819a191feee347fd7b70696a2696f209 100644 (file)
@@ -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);