Coverage Report

Created: 2026-04-29 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
};