]> git.ipfire.org Git - people/ms/network.git/blob - src/networkd/port-bonding.c
b1d2c182e1bc34ef7d378917c4726182238ca3f1
[people/ms/network.git] / src / networkd / port-bonding.c
1 /*#############################################################################
2 # #
3 # IPFire.org - A linux based firewall #
4 # Copyright (C) 2023 IPFire Network Development Team #
5 # #
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. #
10 # #
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. #
15 # #
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/>. #
18 # #
19 #############################################################################*/
20
21 #include <systemd/sd-netlink.h>
22
23 #include "config.h"
24 #include "daemon.h"
25 #include "logging.h"
26 #include "port.h"
27 #include "port-bonding.h"
28 #include "string.h"
29
30 const nw_string_table_t nw_port_bonding_mode[] = {
31 { NW_BONDING_MODE_ROUNDROBIN, "round-robin" },
32 { NW_BONDING_MODE_ACTIVEBACKUP, "active-backup" },
33 { NW_BONDING_MODE_XOR, "xor" },
34 { NW_BONDING_MODE_BROADCAST, "broadcast" },
35 { NW_BONDING_MODE_8023AD, "802.3ad" },
36 { NW_BONDING_MODE_TLB, "tlb" },
37 { NW_BONDING_MODE_ALB, "alb" },
38 { -1, NULL },
39 };
40
41 NW_STRING_TABLE_LOOKUP(nw_port_bonding_mode_t, nw_port_bonding_mode)
42
43 static int nw_port_bonding_read_mode(nw_config* config,
44 const char* key, void* value, void* data) {
45 int* mode = (int*)value;
46
47 const char* p = nw_config_get(config, key);
48 if (p) {
49 *mode = nw_port_bonding_mode_from_string(p);
50 if (!*mode)
51 return -errno;
52 }
53
54 return 0;
55 }
56
57 static int nw_port_bonding_write_mode(nw_config* config,
58 const char* key, const void* value, void* data) {
59 const int* mode = (int*)value;
60
61 return nw_config_set(config, key, nw_port_bonding_mode_to_string(*mode));
62 }
63
64 static int nw_port_bonding_setup(nw_port* port) {
65 int r;
66
67 // Mode
68 r = NW_CONFIG_OPTION(port->config, "BONDING_MODE", &port->bonding.mode,
69 nw_port_bonding_read_mode, nw_port_bonding_write_mode, NULL);
70 if (r < 0)
71 return r;
72
73 return 0;
74 }
75
76 static int nw_port_bonding_create_link(nw_port* port, sd_netlink_message* m) {
77 int r;
78
79 // Set mode
80 r = sd_netlink_message_append_u8(m, IFLA_BOND_MODE, port->bonding.mode);
81 if (r < 0)
82 return r;
83
84 return 0;
85 }
86
87 static int nw_port_bonding_to_json(nw_port* port, struct json_object* o) {
88 int r;
89
90 // Add mode
91 r = json_object_add_string(o, "BondingMode",
92 nw_port_bonding_mode_to_string(port->bonding.mode));
93 if (r < 0)
94 goto ERROR;
95
96 ERROR:
97 return r;
98 }
99
100 const nw_port_info_t nw_port_info_bonding = {
101 .kind = "bond",
102
103 // Operations
104 .ops = {
105 // Configuration
106 .setup = nw_port_bonding_setup,
107
108 // Link
109 .create_link = nw_port_bonding_create_link,
110
111 // JSON
112 .to_json = nw_port_bonding_to_json,
113 },
114 };
115
116 const char* nw_port_bonding_get_mode(nw_port* port) {
117 return nw_port_bonding_mode_to_string(port->bonding.mode);
118 }
119
120 int nw_port_bonding_set_mode(nw_port* port, const char* mode) {
121 const int m = nw_port_bonding_mode_from_string(mode);
122
123 switch (m) {
124 case BOND_MODE_ROUNDROBIN:
125 case BOND_MODE_ACTIVEBACKUP:
126 case BOND_MODE_XOR:
127 case BOND_MODE_BROADCAST:
128 case BOND_MODE_8023AD:
129 case BOND_MODE_TLB:
130 case BOND_MODE_ALB:
131 port->bonding.mode = m;
132 break;
133
134 default:
135 ERROR("%s: Unsupported bonding mode '%s'\n", port->name, mode);
136 errno = ENOTSUP;
137 return 1;
138 }
139
140 return 0;
141 }