]> git.ipfire.org Git - network.git/commitdiff
ports: Add the most basic supports for bonding
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 5 Jun 2023 14:51:41 +0000 (14:51 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 5 Jun 2023 14:51:41 +0000 (14:51 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/networkd/port-bonding.c [new file with mode: 0644]
src/networkd/port-bonding.h [new file with mode: 0644]
src/networkd/port.c
src/networkd/port.h

index 273302b3f92036b9307fc8325edd09530e98b719..ad42f49cbe8fcd6e75ef2e20bb74826d4543feed 100644 (file)
@@ -330,6 +330,8 @@ dist_networkd_SOURCES = \
        src/networkd/ports.h \
        src/networkd/port.c \
        src/networkd/port.h \
+       src/networkd/port-bonding.c \
+       src/networkd/port-bonding.h \
        src/networkd/port-bus.c \
        src/networkd/port-bus.h \
        src/networkd/port-dummy.c \
diff --git a/src/networkd/port-bonding.c b/src/networkd/port-bonding.c
new file mode 100644 (file)
index 0000000..6bddc43
--- /dev/null
@@ -0,0 +1,142 @@
+/*#############################################################################
+#                                                                             #
+# 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 <systemd/sd-netlink.h>
+
+#include "config.h"
+#include "daemon.h"
+#include "logging.h"
+#include "port.h"
+#include "port-bonding.h"
+#include "string.h"
+
+const struct nw_port_bonding_mode {
+       const int mode;
+       const char* string;
+} nw_port_bonding_modes[] = {
+       { BOND_MODE_ROUNDROBIN,   "round-robin" },
+       { BOND_MODE_ACTIVEBACKUP, "active-backup" },
+       { BOND_MODE_XOR,          "xor" },
+       { BOND_MODE_BROADCAST,    "broadcast" },
+       { BOND_MODE_8023AD,       "802.3ad" },
+       { BOND_MODE_TLB,          "tlb" },
+       { BOND_MODE_ALB,          "alb" },
+       { -1, NULL },
+};
+
+static int nw_port_bonding_mode_from_string(const char* string) {
+       const struct nw_port_bonding_mode* m = NULL;
+
+       for (m = nw_port_bonding_modes; m->string; m++) {
+               if (strcmp(m->string, string) == 0)
+                       return m->mode;
+       }
+
+       return -1;
+}
+
+static const char* nw_port_bonding_mode_to_string(const int mode) {
+       const struct nw_port_bonding_mode* m = NULL;
+
+       for (m = nw_port_bonding_modes; m->string; m++) {
+               if (m->mode == mode)
+                       return m->string;
+       }
+
+       return NULL;
+}
+
+static int nw_port_bonding_config_read(nw_port* port) {
+       int r;
+
+       // Mode
+       const char* mode = nw_config_get(port->config, "BONDING_MODE");
+       if (mode) {
+               r = nw_port_bonding_set_mode(port, mode);
+               if (r)
+                       return r;
+       }
+
+       return 0;
+}
+
+static int nw_port_bonding_config_write(nw_port* port) {
+       int r;
+
+       // Mode
+       r = nw_config_set(port->config, "BONDING_MODE",
+                       nw_port_bonding_mode_to_string(port->bonding.mode));
+       if (r)
+               return r;
+
+       return 0;
+}
+
+static int nw_port_bonding_create_link(nw_port* port, sd_netlink_message* m) {
+       int r;
+
+       // Set mode
+       r = sd_netlink_message_append_u8(m, IFLA_BOND_MODE, port->bonding.mode);
+       if (r < 0)
+               return r;
+
+       return 0;
+}
+
+const nw_port_info_t nw_port_info_bonding = {
+       .kind = "bond",
+
+       // Operations
+       .ops = {
+               // Configuration
+               .config_read = nw_port_bonding_config_read,
+               .config_write = nw_port_bonding_config_write,
+
+               // Link
+               .create_link = nw_port_bonding_create_link,
+       },
+};
+
+const char* nw_port_bonding_get_mode(nw_port* port) {
+       return nw_port_bonding_mode_to_string(port->bonding.mode);
+}
+
+int nw_port_bonding_set_mode(nw_port* port, const char* mode) {
+       const int m = nw_port_bonding_mode_from_string(mode);
+
+       switch (m) {
+               case BOND_MODE_ROUNDROBIN:
+               case BOND_MODE_ACTIVEBACKUP:
+               case BOND_MODE_XOR:
+               case BOND_MODE_BROADCAST:
+               case BOND_MODE_8023AD:
+               case BOND_MODE_TLB:
+               case BOND_MODE_ALB:
+                       port->bonding.mode = m;
+                       break;
+
+               default:
+                       ERROR("%s: Unsupported bonding mode '%s'\n", port->name, mode);
+                       errno = ENOTSUP;
+                       return 1;
+       }
+
+       return 0;
+}
diff --git a/src/networkd/port-bonding.h b/src/networkd/port-bonding.h
new file mode 100644 (file)
index 0000000..5cd2c43
--- /dev/null
@@ -0,0 +1,37 @@
+/*#############################################################################
+#                                                                             #
+# 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_BONDING_H
+#define NETWORKD_PORT_BONDING_H
+
+#include <linux/if_bonding.h>
+
+#include "port.h"
+
+struct nw_port_bonding {
+       int mode;
+};
+
+extern const nw_port_info_t nw_port_info_bonding;
+
+const char* nw_port_bonding_get_mode(nw_port* port);
+int nw_port_bonding_set_mode(nw_port* port, const char* mode);
+
+#endif /* NETWORKD_PORT_BONDING_H */
index d5ffe42c890da7fa221bec29ea2f18420d7f482d..b44cc8822fef7bfc0e68c076b994c2b0a45359fd 100644 (file)
@@ -30,6 +30,7 @@
 #include "link.h"
 #include "logging.h"
 #include "port.h"
+#include "port-bonding.h"
 #include "port-dummy.h"
 #include "port-vlan.h"
 #include "stats-collector.h"
@@ -39,6 +40,7 @@ static const struct nw_port_type_map {
        nw_port_type_t type;
        const char* name;
 } nw_port_type_map[] = {
+       { NW_PORT_BONDING, "bonding" },
        { NW_PORT_DUMMY,   "dummy" },
        { NW_PORT_VLAN,    "vlan" },
        { NW_PORT_UNKNOWN, NULL },
@@ -210,6 +212,10 @@ int nw_port_create(nw_port** port, nw_daemon* daemon, nw_port_type_t type, const
 
        // Set operations
        switch (p->type) {
+               case NW_PORT_BONDING:
+                       p->info = &nw_port_info_bonding;
+                       break;
+
                case NW_PORT_DUMMY:
                        p->info = &nw_port_info_dummy;
                        break;
@@ -337,6 +343,7 @@ int __nw_port_drop_port(nw_daemon* daemon, nw_port* port, void* data) {
                        }
                        break;
 
+               case NW_PORT_BONDING:
                case NW_PORT_DUMMY:
                case NW_PORT_UNKNOWN:
                        break;
index 8bc4db8af32e9aa0c7eabdd988a60ee12b06c3ef..f8beed3b59e37871ba301913563c9e3f175b277c 100644 (file)
@@ -31,6 +31,7 @@
 
 typedef enum nw_port_type {
        NW_PORT_UNKNOWN = 0,
+       NW_PORT_BONDING,
        NW_PORT_DUMMY,
        NW_PORT_VLAN,
 } nw_port_type_t;
@@ -41,12 +42,14 @@ typedef enum nw_port_type {
 #define NW_VLAN_ID_MAX                 4096
 
 typedef struct nw_port nw_port;
+typedef struct nw_port_info nw_port_info_t;
 
 #include "address.h"
 #include "config.h"
 #include "daemon.h"
+#include "port-bonding.h"
 
-typedef struct nw_port_info {
+struct nw_port_info {
        // IFLA_INFO_KIND/IFLA_INFO_DATA
        const char* kind;
 
@@ -62,7 +65,7 @@ typedef struct nw_port_info {
                int (*create_link)(nw_port* port, sd_netlink_message* message);
                int (*destroy_link)(nw_port* port);
        } ops;
-} nw_port_info_t;
+};
 
 #define NW_PORT_INFO(port) (port->info)
 #define NW_PORT_OPS(port) (&NW_PORT_INFO(port)->ops)
@@ -86,6 +89,9 @@ struct nw_port {
        // Type Operations
        const nw_port_info_t* info;
 
+       // Bonding Settings
+       struct nw_port_bonding bonding;
+
        // VLAN settings
        struct nw_port_vlan {
                nw_port* parent;