/src/systemd/src/network/netdev/batadv.c
Line | Count | Source |
1 | | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | | |
3 | | #include <linux/if_arp.h> |
4 | | |
5 | | #include "sd-netlink.h" |
6 | | |
7 | | #include "batadv.h" |
8 | | #include "conf-parser.h" |
9 | | #include "netlink-util.h" |
10 | | #include "networkd-manager.h" |
11 | | #include "parse-util.h" |
12 | | #include "string-table.h" |
13 | | |
14 | 150 | static void batadv_init(NetDev *n) { |
15 | 150 | BatmanAdvanced *b = BATADV(n); |
16 | | |
17 | | /* Set defaults */ |
18 | 150 | b->aggregation = true; |
19 | 150 | b->gateway_bandwidth_down = 10000; |
20 | 150 | b->gateway_bandwidth_up = 2000; |
21 | 150 | b->bridge_loop_avoidance = true; |
22 | 150 | b->distributed_arp_table = true; |
23 | 150 | b->fragmentation = true; |
24 | 150 | b->hop_penalty = 15; |
25 | 150 | b->originator_interval = 1000; |
26 | 150 | b->routing_algorithm = BATADV_ROUTING_ALGORITHM_BATMAN_V; |
27 | 150 | } |
28 | | |
29 | | static const char* const batadv_gateway_mode_table[_BATADV_GATEWAY_MODE_MAX] = { |
30 | | [BATADV_GATEWAY_MODE_OFF] = "off", |
31 | | [BATADV_GATEWAY_MODE_CLIENT] = "client", |
32 | | [BATADV_GATEWAY_MODE_SERVER] = "server", |
33 | | }; |
34 | | |
35 | | static const char* const batadv_routing_algorithm_table[_BATADV_ROUTING_ALGORITHM_MAX] = { |
36 | | [BATADV_ROUTING_ALGORITHM_BATMAN_V] = "batman-v", |
37 | | [BATADV_ROUTING_ALGORITHM_BATMAN_IV] = "batman-iv", |
38 | | }; |
39 | | |
40 | | static const char* const batadv_routing_algorithm_kernel_table[_BATADV_ROUTING_ALGORITHM_MAX] = { |
41 | | [BATADV_ROUTING_ALGORITHM_BATMAN_V] = "BATMAN_V", |
42 | | [BATADV_ROUTING_ALGORITHM_BATMAN_IV] = "BATMAN_IV", |
43 | | }; |
44 | | |
45 | | DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(batadv_gateway_mode, BatadvGatewayModes); |
46 | 1.55k | DEFINE_CONFIG_PARSE_ENUM(config_parse_batadv_gateway_mode, batadv_gateway_mode, BatadvGatewayModes); |
47 | 1.55k | |
48 | 1.55k | DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(batadv_routing_algorithm, BatadvRoutingAlgorithm); |
49 | 1.56k | DEFINE_CONFIG_PARSE_ENUM(config_parse_batadv_routing_algorithm, batadv_routing_algorithm, BatadvRoutingAlgorithm); |
50 | 1.56k | |
51 | 1.56k | DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(batadv_routing_algorithm_kernel, BatadvRoutingAlgorithm); |
52 | 1.56k | |
53 | 1.56k | int config_parse_badadv_bandwidth ( |
54 | 1.56k | const char *unit, |
55 | 1.56k | const char *filename, |
56 | 1.56k | unsigned line, |
57 | 1.56k | const char *section, |
58 | 1.56k | unsigned section_line, |
59 | 1.56k | const char *lvalue, |
60 | 1.56k | int ltype, |
61 | 1.56k | const char *rvalue, |
62 | 1.56k | void *data, |
63 | 1.56k | void *userdata) { |
64 | | |
65 | 671 | uint64_t k; |
66 | 671 | uint32_t *bandwidth = data; |
67 | 671 | int r; |
68 | | |
69 | 671 | assert(filename); |
70 | 671 | assert(lvalue); |
71 | 671 | assert(rvalue); |
72 | | |
73 | 671 | r = parse_size(rvalue, 1000, &k); |
74 | 671 | if (r < 0) { |
75 | 194 | log_syntax(unit, LOG_WARNING, filename, line, r, |
76 | 194 | "Failed to parse '%s=', ignoring assignment: %s", |
77 | 194 | lvalue, rvalue); |
78 | 194 | return 0; |
79 | 194 | } |
80 | | |
81 | 477 | if (k/1000/100 > UINT32_MAX) |
82 | 222 | log_syntax(unit, LOG_WARNING, filename, line, 0, |
83 | 477 | "The value of '%s=', is outside of 0...429496729500000 range: %s", |
84 | 477 | lvalue, rvalue); |
85 | | |
86 | 477 | *bandwidth = k/1000/100; |
87 | | |
88 | 477 | return 0; |
89 | 671 | } |
90 | | |
91 | | /* callback for batman netdev's parameter set */ |
92 | 0 | static int netdev_batman_set_handler(sd_netlink *rtnl, sd_netlink_message *m, NetDev *netdev) { |
93 | 0 | int r; |
94 | |
|
95 | 0 | assert(netdev); |
96 | 0 | assert(m); |
97 | |
|
98 | 0 | r = sd_netlink_message_get_errno(m); |
99 | 0 | if (r < 0) { |
100 | 0 | log_netdev_warning_errno(netdev, r, "BATADV parameters could not be set: %m"); |
101 | 0 | return 1; |
102 | 0 | } |
103 | | |
104 | 0 | log_netdev_debug(netdev, "BATADV parameters set success"); |
105 | |
|
106 | 0 | return 1; |
107 | 0 | } |
108 | | |
109 | 0 | static int netdev_batadv_post_create_message(NetDev *netdev, sd_netlink_message *message) { |
110 | 0 | BatmanAdvanced *b = BATADV(netdev); |
111 | 0 | int r; |
112 | |
|
113 | 0 | r = sd_netlink_message_append_u32(message, BATADV_ATTR_MESH_IFINDEX, netdev->ifindex); |
114 | 0 | if (r < 0) |
115 | 0 | return r; |
116 | | |
117 | 0 | r = sd_netlink_message_append_u8(message, BATADV_ATTR_GW_MODE, b->gateway_mode); |
118 | 0 | if (r < 0) |
119 | 0 | return r; |
120 | | |
121 | 0 | r = sd_netlink_message_append_u8(message, BATADV_ATTR_AGGREGATED_OGMS_ENABLED, b->aggregation); |
122 | 0 | if (r < 0) |
123 | 0 | return r; |
124 | | |
125 | 0 | r = sd_netlink_message_append_u8(message, BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED, b->bridge_loop_avoidance); |
126 | 0 | if (r < 0) |
127 | 0 | return r; |
128 | | |
129 | 0 | r = sd_netlink_message_append_u8(message, BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED, b->distributed_arp_table); |
130 | 0 | if (r < 0) |
131 | 0 | return r; |
132 | | |
133 | 0 | r = sd_netlink_message_append_u8(message, BATADV_ATTR_FRAGMENTATION_ENABLED, b->fragmentation); |
134 | 0 | if (r < 0) |
135 | 0 | return r; |
136 | | |
137 | 0 | r = sd_netlink_message_append_u8(message, BATADV_ATTR_HOP_PENALTY, b->hop_penalty); |
138 | 0 | if (r < 0) |
139 | 0 | return r; |
140 | | |
141 | 0 | r = sd_netlink_message_append_u32(message, BATADV_ATTR_ORIG_INTERVAL, DIV_ROUND_UP(b->originator_interval, USEC_PER_MSEC)); |
142 | 0 | if (r < 0) |
143 | 0 | return r; |
144 | | |
145 | 0 | r = sd_netlink_message_append_u32(message, BATADV_ATTR_GW_BANDWIDTH_DOWN, b->gateway_bandwidth_down); |
146 | 0 | if (r < 0) |
147 | 0 | return r; |
148 | | |
149 | 0 | r = sd_netlink_message_append_u32(message, BATADV_ATTR_GW_BANDWIDTH_UP, b->gateway_bandwidth_up); |
150 | 0 | if (r < 0) |
151 | 0 | return r; |
152 | | |
153 | 0 | return 0; |
154 | 0 | } |
155 | | |
156 | 0 | static int netdev_batadv_post_create(NetDev *netdev, Link *link) { |
157 | 0 | _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; |
158 | 0 | int r; |
159 | |
|
160 | 0 | assert(netdev); |
161 | |
|
162 | 0 | if (!netdev_is_managed(netdev)) |
163 | 0 | return 0; /* Already detached, due to e.g. reloading .netdev files. */ |
164 | | |
165 | 0 | r = sd_genl_message_new(netdev->manager->genl, BATADV_NL_NAME, BATADV_CMD_SET_MESH, &message); |
166 | 0 | if (r < 0) |
167 | 0 | return log_netdev_error_errno(netdev, r, "Could not allocate netlink message: %m"); |
168 | | |
169 | 0 | r = netdev_batadv_post_create_message(netdev, message); |
170 | 0 | if (r < 0) |
171 | 0 | return log_netdev_error_errno(netdev, r, "Could not create netlink message: %m"); |
172 | | |
173 | 0 | r = netlink_call_async(netdev->manager->genl, NULL, message, netdev_batman_set_handler, |
174 | 0 | netdev_destroy_callback, netdev); |
175 | 0 | if (r < 0) |
176 | 0 | return log_netdev_error_errno(netdev, r, "Could not send netlink message: %m"); |
177 | | |
178 | 0 | netdev_ref(netdev); |
179 | |
|
180 | 0 | return r; |
181 | 0 | } |
182 | | |
183 | 0 | static int netdev_batadv_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { |
184 | 0 | assert(m); |
185 | |
|
186 | 0 | BatmanAdvanced *b = BATADV(netdev); |
187 | 0 | int r; |
188 | |
|
189 | 0 | r = sd_netlink_message_append_string(m, IFLA_BATADV_ALGO_NAME, batadv_routing_algorithm_kernel_to_string(b->routing_algorithm)); |
190 | 0 | if (r < 0) |
191 | 0 | return r; |
192 | | |
193 | 0 | return 0; |
194 | 0 | } |
195 | | |
196 | | const NetDevVTable batadv_vtable = { |
197 | | .object_size = sizeof(BatmanAdvanced), |
198 | | .init = batadv_init, |
199 | | .sections = NETDEV_COMMON_SECTIONS "BatmanAdvanced\0", |
200 | | .fill_message_create = netdev_batadv_fill_message_create, |
201 | | .post_create = netdev_batadv_post_create, |
202 | | .create_type = NETDEV_CREATE_INDEPENDENT, |
203 | | .iftype = ARPHRD_ETHER, |
204 | | .generate_mac = true, |
205 | | }; |