• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 14630481637

23 Apr 2025 07:04PM UTC coverage: 72.178% (-0.002%) from 72.18%
14630481637

push

github

DaanDeMeyer
mkosi: Run clangd within the tools tree instead of the build container

Running within the build sandbox has a number of disadvantages:
- We have a separate clangd cache for each distribution/release combo
- It requires to build the full image before clangd can be used
- It breaks every time the image becomes out of date and requires a
  rebuild
- We can't look at system headers as we don't have the knowledge to map
  them from inside the build sandbox to the corresponding path on the host

Instead, let's have mkosi.clangd run clangd within the tools tree. We
already require building systemd for both the host and the target anyway,
and all the dependencies to build systemd are installed in the tools tree
already for that, as well as clangd since it's installed together with the
other clang tooling we install in the tools tree. Unlike the previous approach,
this approach only requires the mkosi tools tree to be built upfront, which has
a much higher chance of not invalidating its cache. We can also trivially map
system header lookups from within the sandbox to the path within mkosi.tools
on the host so that starts working as well.

297054 of 411557 relevant lines covered (72.18%)

686269.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

56.52
/src/network/netdev/vxlan.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
/* Make sure the net/if.h header is included before any linux/ one */
4
#include <net/if.h>
5
#include <netinet/in.h>
6
#include <linux/if_arp.h>
7

8
#include "conf-parser.h"
9
#include "alloc-util.h"
10
#include "extract-word.h"
11
#include "networkd-link.h"
12
#include "string-table.h"
13
#include "string-util.h"
14
#include "strv.h"
15
#include "parse-util.h"
16
#include "vxlan.h"
17

18
static const char* const df_table[_NETDEV_VXLAN_DF_MAX] = {
19
        [NETDEV_VXLAN_DF_NO]      = "no",
20
        [NETDEV_VXLAN_DF_YES]     = "yes",
21
        [NETDEV_VXLAN_DF_INHERIT] = "inherit",
22
};
23

24
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(df, VxLanDF, NETDEV_VXLAN_DF_YES);
×
25
DEFINE_CONFIG_PARSE_ENUM(config_parse_df, df, VxLanDF);
×
26

27
static int vxlan_get_local_address(VxLan *v, Link *link, int *ret_family, union in_addr_union *ret_address) {
154✔
28
        assert(v);
154✔
29

30
        if (v->local_type < 0) {
154✔
31
                if (ret_family)
6✔
32
                        *ret_family = v->local_family;
4✔
33
                if (ret_address)
6✔
34
                        *ret_address = v->local;
4✔
35
                return 0;
6✔
36
        }
37

38
        return link_get_local_address(link, v->local_type, v->local_family, ret_family, ret_address);
148✔
39
}
40

41
static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
6✔
42
        assert(m);
6✔
43

44
        union in_addr_union local;
6✔
45
        int local_family, r;
6✔
46
        VxLan *v = VXLAN(netdev);
6✔
47

48
        if (in_addr_is_set(v->group_family, &v->group)) {
6✔
49
                if (v->group_family == AF_INET)
×
50
                        r = sd_netlink_message_append_in_addr(m, IFLA_VXLAN_GROUP, &v->group.in);
×
51
                else
52
                        r = sd_netlink_message_append_in6_addr(m, IFLA_VXLAN_GROUP6, &v->group.in6);
×
53
                if (r < 0)
×
54
                        return r;
6✔
55
        } else if (in_addr_is_set(v->remote_family, &v->remote)) {
6✔
56
                if (v->remote_family == AF_INET)
×
57
                        r = sd_netlink_message_append_in_addr(m, IFLA_VXLAN_GROUP, &v->remote.in);
×
58
                else
59
                        r = sd_netlink_message_append_in6_addr(m, IFLA_VXLAN_GROUP6, &v->remote.in6);
×
60
                if (r < 0)
×
61
                        return r;
62
        }
63

64
        r = vxlan_get_local_address(v, link, &local_family, &local);
6✔
65
        if (r < 0)
6✔
66
                return r;
67

68
        if (in_addr_is_set(local_family, &local)) {
6✔
69
                if (local_family == AF_INET)
3✔
70
                        r = sd_netlink_message_append_in_addr(m, IFLA_VXLAN_LOCAL, &local.in);
×
71
                else
72
                        r = sd_netlink_message_append_in6_addr(m, IFLA_VXLAN_LOCAL6, &local.in6);
3✔
73
                if (r < 0)
3✔
74
                        return r;
75
        }
76

77
        r = sd_netlink_message_append_u32(m, IFLA_VXLAN_LINK, link ? link->ifindex : 0);
6✔
78
        if (r < 0)
6✔
79
                return r;
80

81
        r = sd_netlink_message_append_u8(m, IFLA_VXLAN_TTL, v->ttl);
6✔
82
        if (r < 0)
6✔
83
                return r;
84

85
        if (v->fdb_ageing != 0) {
6✔
86
                r = sd_netlink_message_append_u32(m, IFLA_VXLAN_AGEING, v->fdb_ageing / USEC_PER_SEC);
×
87
                if (r < 0)
×
88
                        return r;
89
        }
90

91
        if (v->tos != 0) {
6✔
92
                r = sd_netlink_message_append_u8(m, IFLA_VXLAN_TOS, v->tos);
×
93
                if (r < 0)
×
94
                        return r;
95
        }
96

97
        r = sd_netlink_message_append_u32(m, IFLA_VXLAN_LABEL, htobe32(v->flow_label));
6✔
98
        if (r < 0)
6✔
99
                return r;
100

101
        if (v->df != _NETDEV_VXLAN_DF_INVALID) {
6✔
102
                r = sd_netlink_message_append_u8(m, IFLA_VXLAN_DF, v->df);
×
103
                if (r < 0)
×
104
                        return r;
105
        }
106

107
        if (netdev->ifindex > 0)
6✔
108
                return 0;
109

110
        /* The properties below cannot be updated, and the kernel refuses the whole request if one of the
111
         * following attributes is set for an existing interface. */
112

113
        if (!v->external && v->vni <= VXLAN_VID_MAX) {
5✔
114
                r = sd_netlink_message_append_u32(m, IFLA_VXLAN_ID, v->vni);
4✔
115
                if (r < 0)
4✔
116
                        return r;
117
        }
118

119
        if (v->inherit) {
5✔
120
                r = sd_netlink_message_append_flag(m, IFLA_VXLAN_TTL_INHERIT);
×
121
                if (r < 0)
×
122
                        return r;
123
        }
124

125
        r = sd_netlink_message_append_u8(m, IFLA_VXLAN_LEARNING, v->learning);
5✔
126
        if (r < 0)
5✔
127
                return r;
128

129
        r = sd_netlink_message_append_u8(m, IFLA_VXLAN_RSC, v->route_short_circuit);
5✔
130
        if (r < 0)
5✔
131
                return r;
132

133
        r = sd_netlink_message_append_u8(m, IFLA_VXLAN_PROXY, v->arp_proxy);
5✔
134
        if (r < 0)
5✔
135
                return r;
136

137
        r = sd_netlink_message_append_u8(m, IFLA_VXLAN_L2MISS, v->l2miss);
5✔
138
        if (r < 0)
5✔
139
                return r;
140

141
        r = sd_netlink_message_append_u8(m, IFLA_VXLAN_L3MISS, v->l3miss);
5✔
142
        if (r < 0)
5✔
143
                return r;
144

145
        if (v->max_fdb != 0) {
5✔
146
                r = sd_netlink_message_append_u32(m, IFLA_VXLAN_LIMIT, v->max_fdb);
×
147
                if (r < 0)
×
148
                        return r;
149
        }
150

151
        r = sd_netlink_message_append_u8(m, IFLA_VXLAN_UDP_CSUM, v->udpcsum);
5✔
152
        if (r < 0)
5✔
153
                return r;
154

155
        r = sd_netlink_message_append_u8(m, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, v->udp6zerocsumtx);
5✔
156
        if (r < 0)
5✔
157
                return r;
158

159
        r = sd_netlink_message_append_u8(m, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, v->udp6zerocsumrx);
5✔
160
        if (r < 0)
5✔
161
                return r;
162

163
        r = sd_netlink_message_append_u8(m, IFLA_VXLAN_REMCSUM_TX, v->remote_csum_tx);
5✔
164
        if (r < 0)
5✔
165
                return r;
166

167
        r = sd_netlink_message_append_u8(m, IFLA_VXLAN_REMCSUM_RX, v->remote_csum_rx);
5✔
168
        if (r < 0)
5✔
169
                return r;
170

171
        r = sd_netlink_message_append_u16(m, IFLA_VXLAN_PORT, htobe16(v->dest_port));
5✔
172
        if (r < 0)
5✔
173
                return r;
174

175
        if (v->port_range.low != 0 || v->port_range.high != 0) {
5✔
176
                struct ifla_vxlan_port_range port_range;
×
177

178
                port_range.low = htobe16(v->port_range.low);
×
179
                port_range.high = htobe16(v->port_range.high);
×
180

181
                r = sd_netlink_message_append_data(m, IFLA_VXLAN_PORT_RANGE, &port_range, sizeof(port_range));
×
182
                if (r < 0)
×
183
                        return r;
×
184
        }
185

186
        if (v->group_policy) {
5✔
187
                r = sd_netlink_message_append_flag(m, IFLA_VXLAN_GBP);
3✔
188
                if (r < 0)
3✔
189
                        return r;
190
        }
191

192
        if (v->generic_protocol_extension) {
5✔
193
                r = sd_netlink_message_append_flag(m, IFLA_VXLAN_GPE);
×
194
                if (r < 0)
×
195
                        return r;
196
        }
197

198
        r = sd_netlink_message_append_u8(m, IFLA_VXLAN_COLLECT_METADATA, v->external);
5✔
199
        if (r < 0)
5✔
200
                return r;
201

202
        if (v->external) {
5✔
203
                r = sd_netlink_message_append_u8(m, IFLA_VXLAN_VNIFILTER, v->vnifilter);
1✔
204
                if (r < 0)
1✔
205
                        return r;
×
206
        }
207

208
        return 0;
209
}
210

211
static bool vxlan_can_set_mac(NetDev *netdev, const struct hw_addr_data *hw_addr) {
×
212
        return true;
×
213
}
214

215
static bool vxlan_can_set_mtu(NetDev *netdev, uint32_t mtu) {
×
216
        assert(netdev);
×
217

218
        /* MTU cannot be updated. Even unchanged, IFLA_MTU attribute cannot be set in the message. */
219
        return netdev->ifindex <= 0;
×
220
}
221

222
int config_parse_vxlan_address(
2✔
223
                const char *unit,
224
                const char *filename,
225
                unsigned line,
226
                const char *section,
227
                unsigned section_line,
228
                const char *lvalue,
229
                int ltype,
230
                const char *rvalue,
231
                void *data,
232
                void *userdata) {
233

234
        VxLan *v = ASSERT_PTR(userdata);
2✔
235
        union in_addr_union *addr = data, buffer;
2✔
236
        int *family, f, r;
2✔
237

238
        assert(filename);
2✔
239
        assert(lvalue);
2✔
240
        assert(rvalue);
2✔
241
        assert(data);
2✔
242

243
        if (streq(lvalue, "Local"))
2✔
244
                family = &v->local_family;
2✔
245
        else if (streq(lvalue, "Remote"))
×
246
                family = &v->remote_family;
×
247
        else if (streq(lvalue, "Group"))
×
248
                family = &v->group_family;
×
249
        else
250
                assert_not_reached();
×
251

252
        if (isempty(rvalue)) {
2✔
253
                *addr = IN_ADDR_NULL;
×
254
                *family = AF_UNSPEC;
×
255
                return 0;
×
256
        }
257

258
        if (streq(lvalue, "Local")) {
2✔
259
                NetDevLocalAddressType t;
2✔
260

261
                t = netdev_local_address_type_from_string(rvalue);
2✔
262
                if (t >= 0) {
2✔
263
                        v->local = IN_ADDR_NULL;
1✔
264
                        v->local_family = AF_UNSPEC;
1✔
265
                        v->local_type = t;
1✔
266
                        return 0;
1✔
267
                }
268
        }
269

270
        r = in_addr_from_string_auto(rvalue, &f, &buffer);
1✔
271
        if (r < 0) {
1✔
272
                log_syntax(unit, LOG_WARNING, filename, line, r,
×
273
                           "Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
274
                return 0;
×
275
        }
276

277
        r = in_addr_is_multicast(f, &buffer);
1✔
278

279
        if (streq(lvalue, "Group")) {
1✔
280
                if (r <= 0) {
×
281
                        log_syntax(unit, LOG_WARNING, filename, line, 0,
×
282
                                   "%s= must be a multicast address, ignoring assignment: %s", lvalue, rvalue);
283
                        return 0;
×
284
                }
285
        } else {
286
                if (r > 0) {
1✔
287
                        log_syntax(unit, LOG_WARNING, filename, line, 0,
×
288
                                   "%s= cannot be a multicast address, ignoring assignment: %s", lvalue, rvalue);
289
                        return 0;
×
290
                }
291
        }
292

293
        if (streq(lvalue, "Local"))
1✔
294
                v->local_type = _NETDEV_LOCAL_ADDRESS_TYPE_INVALID;
1✔
295
        *addr = buffer;
1✔
296
        *family = f;
1✔
297

298
        return 0;
1✔
299
}
300

301
int config_parse_port_range(
×
302
                const char *unit,
303
                const char *filename,
304
                unsigned line,
305
                const char *section,
306
                unsigned section_line,
307
                const char *lvalue,
308
                int ltype,
309
                const char *rvalue,
310
                void *data,
311
                void *userdata) {
312

313
        assert(filename);
×
314
        assert(lvalue);
×
315
        assert(rvalue);
×
316
        assert(data);
×
317

318
        VxLan *v = ASSERT_PTR(userdata);
×
319
        int r;
×
320

321
        r = parse_ip_port_range(rvalue, &v->port_range.low, &v->port_range.high, /* allow_zero = */ false);
×
322
        if (r < 0)
×
323
                log_syntax(unit, LOG_WARNING, filename, line, r,
×
324
                           "Failed to parse VXLAN port range '%s'. Port should be greater than 0 and less than 65535.", rvalue);
325
        return 0;
×
326
}
327

328
int config_parse_flow_label(
×
329
                const char *unit,
330
                const char *filename,
331
                unsigned line,
332
                const char *section,
333
                unsigned section_line,
334
                const char *lvalue,
335
                int ltype,
336
                const char *rvalue,
337
                void *data,
338
                void *userdata) {
339

340
        VxLan *v = userdata;
×
341
        unsigned f;
×
342
        int r;
×
343

344
        assert(filename);
×
345
        assert(lvalue);
×
346
        assert(rvalue);
×
347
        assert(data);
×
348

349
        r = safe_atou(rvalue, &f);
×
350
        if (r < 0) {
×
351
                log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse VXLAN flow label '%s'.", rvalue);
×
352
                return 0;
×
353
        }
354

355
        if (f & ~VXLAN_FLOW_LABEL_MAX_MASK) {
×
356
                log_syntax(unit, LOG_WARNING, filename, line, r,
×
357
                           "VXLAN flow label '%s' not valid. Flow label range should be [0-1048575].", rvalue);
358
                return 0;
×
359
        }
360

361
        v->flow_label = f;
×
362

363
        return 0;
×
364
}
365

366
int config_parse_vxlan_ttl(
×
367
                const char *unit,
368
                const char *filename,
369
                unsigned line,
370
                const char *section,
371
                unsigned section_line,
372
                const char *lvalue,
373
                int ltype,
374
                const char *rvalue,
375
                void *data,
376
                void *userdata) {
377

378
        assert(filename);
×
379
        assert(lvalue);
×
380
        assert(rvalue);
×
381
        assert(data);
×
382

383
        VxLan *v = ASSERT_PTR(userdata);
×
384
        int r;
×
385

386
        if (streq(rvalue, "inherit")) {
×
387
                v->inherit = true;
×
388
                v->ttl = 0;  /* unset the unused ttl field for clarity */
×
389
                return 0;
×
390
        }
391

392
        r = config_parse_unsigned_bounded(
×
393
                        unit, filename, line, section, section_line, lvalue, rvalue,
394
                        0, UINT8_MAX, true,
395
                        &v->ttl);
396
        if (r <= 0)
×
397
                return r;
398
        v->inherit = false;
×
399
        return 0;
×
400
}
401

402
static int netdev_vxlan_verify(NetDev *netdev, const char *filename) {
5✔
403
        assert(filename);
5✔
404

405
        VxLan *v = VXLAN(netdev);
5✔
406

407
        if (v->ttl > 255)
5✔
408
                return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
×
409
                                                "%s: VXLAN TTL must be <= 255. Ignoring.",
410
                                                filename);
411

412
        if (!v->dest_port && v->generic_protocol_extension)
5✔
413
                v->dest_port = 4790;
×
414

415
        if (in_addr_is_set(v->group_family, &v->group) && in_addr_is_set(v->remote_family, &v->remote))
5✔
416
                return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
×
417
                                                "%s: VXLAN both 'Group=' and 'Remote=' cannot be specified. Ignoring.",
418
                                                filename);
419

420
        if (v->independent && v->local_type >= 0)
5✔
421
                return log_netdev_error_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
×
422
                                              "The local address cannot be '%s' when Independent= is enabled, ignoring.",
423
                                              strna(netdev_local_address_type_to_string(v->local_type)));
424

425
        if (v->external) {
5✔
426
                if (v->vni <= VXLAN_VID_MAX)
1✔
427
                        log_netdev_warning(netdev, "VNI= is set while External= is enabled. VNI= setting will be ignored.");
×
428
        } else {
429
                if (v->vnifilter)
4✔
430
                        log_netdev_warning(netdev, "VNIFilter= is enabled while External= is disabled. VNIFilter= setting will be ignored.");
×
431
                if (v->vni > VXLAN_VID_MAX)
4✔
432
                        return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
×
433
                                                        "%s: VXLAN without valid VNI (or VXLAN Segment ID) configured. Ignoring.",
434
                                                        filename);
435
        }
436

437
        return 0;
438
}
439

440
static bool vxlan_needs_reconfigure(NetDev *netdev, NetDevLocalAddressType type) {
10✔
441
        assert(type >= 0 && type < _NETDEV_LOCAL_ADDRESS_TYPE_MAX);
10✔
442

443
        VxLan *v = VXLAN(netdev);
10✔
444

445
        return v->local_type == type;
10✔
446
}
447

448
static int netdev_vxlan_is_ready_to_create(NetDev *netdev, Link *link) {
150✔
449
        VxLan *v = VXLAN(netdev);
150✔
450

451
        if (v->independent)
150✔
452
                return true;
453

454
        return vxlan_get_local_address(v, link, NULL, NULL) >= 0;
148✔
455
}
456

457
static void vxlan_init(NetDev *netdev) {
5✔
458
        VxLan *v = VXLAN(netdev);
5✔
459

460
        v->local_type = _NETDEV_LOCAL_ADDRESS_TYPE_INVALID;
5✔
461
        v->vni = VXLAN_VID_MAX + 1;
5✔
462
        v->df = _NETDEV_VXLAN_DF_INVALID;
5✔
463
        v->learning = true;
5✔
464
        v->udpcsum = false;
5✔
465
        v->udp6zerocsumtx = false;
5✔
466
        v->udp6zerocsumrx = false;
5✔
467
        v->external = false;
5✔
468
        v->vnifilter = false;
5✔
469
}
5✔
470

471
const NetDevVTable vxlan_vtable = {
472
        .object_size = sizeof(VxLan),
473
        .init = vxlan_init,
474
        .sections = NETDEV_COMMON_SECTIONS "VXLAN\0",
475
        .fill_message_create = netdev_vxlan_fill_message_create,
476
        .create_type = NETDEV_CREATE_STACKED,
477
        .is_ready_to_create = netdev_vxlan_is_ready_to_create,
478
        .config_verify = netdev_vxlan_verify,
479
        .can_set_mac = vxlan_can_set_mac,
480
        .can_set_mtu = vxlan_can_set_mtu,
481
        .needs_reconfigure = vxlan_needs_reconfigure,
482
        .iftype = ARPHRD_ETHER,
483
        .generate_mac = true,
484
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc