mirror of
https://github.com/systemd/systemd.git
synced 2026-07-19 14:00:56 +00:00
The linux/ headers include linux/libc-compat.h that makes sure the
linux/ headers won't redeclare symbols already declared by net/if.h, but
glibc's net/if.h doesn't do that, so if the include order is reversed
we'll end up with a bunch of errors about redeclared stuff:
[3/519] Compiling C object test-network-tables.p/src_network_test-network-tables.c.o
FAILED: test-network-tables.p/src_network_test-network-tables.c.o
cc -Itest-network-tables.p -I. -I.. -Isrc/basic -I../src/basic -Isrc/fundamental -I../src/fundamental -Isrc/systemd -I../src/systemd -I../src/libsystemd/sd-bus -I../src/libsystemd/sd-device -I../src/libsystemd/sd-event -I../src/libsystemd/sd-hwdb -I../src/libsystemd/sd-id128 -I../src/libsystemd/sd-journal -I../src/libsystemd/sd-netlink -I../src/libsystemd/sd-network -I../src/libsystemd/sd-resolve -Isrc/shared -I../src/shared -Isrc/libsystemd-network -I../src/libsystemd-network -Isrc/network -I../src/network -I../src/network/netdev -I../src/network/tc -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -std=gnu11 -O0 -g -Wno-missing-field-initializers -Wno-unused-parameter -Wno-nonnull-compare -Warray-bounds -Warray-bounds=2 -Wdate-time -Wendif-labels -Werror=format=2 -Werror=format-signedness -Werror=implicit-function-declaration -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Werror=missing-declarations -Werror=missing-prototypes -Werror=overflow -Werror=override-init -Werror=return-type -Werror=shift-count-overflow -Werror=shift-overflow=2 -Werror=strict-flex-arrays -Werror=undef -Wfloat-equal -Wimplicit-fallthrough=5 -Winit-self -Wlogical-op -Wmissing-include-dirs -Wmissing-noreturn -Wnested-externs -Wold-style-definition -Wpointer-arith -Wredundant-decls -Wshadow -Wstrict-aliasing=2 -Wstrict-prototypes -Wsuggest-attribute=noreturn -Wunused-function -Wwrite-strings -Wzero-length-bounds -fdiagnostics-show-option -fno-common -fstack-protector -fstack-protector-strong -fstrict-flex-arrays --param=ssp-buffer-size=4 -Wno-unused-result -Werror=shadow -fno-strict-aliasing -fstrict-flex-arrays=1 -fvisibility=hidden -fno-omit-frame-pointer -include config.h -pthread -DTEST_CODE=1 -MD -MQ test-network-tables.p/src_network_test-network-tables.c.o -MF test-network-tables.p/src_network_test-network-tables.c.o.d -o test-network-tables.p/src_network_test-network-tables.c.o -c ../src/network/test-network-tables.c
In file included from ../src/basic/linux/if_bonding.h:47,
from ../src/network/netdev/bond.h:5,
from ../src/network/test-network-tables.c:3:
../src/basic/linux/if.h:111:41: error: redeclaration of enumerator ‘IFF_UP’
111 | #define IFF_UP IFF_UP
| ^~~~~~
../src/basic/linux/if.h:84:9: note: previous definition of ‘IFF_UP’ with type ‘enum net_device_flags’
84 | IFF_UP = 1<<0, /* sysfs */
| ^~~~~~
../src/basic/linux/if.h:112:41: error: redeclaration of enumerator ‘IFF_BROADCAST’
112 | #define IFF_BROADCAST IFF_BROADCAST
| ^~~~~~~~~~~~~
...
This also drops remaining workarounds from the last time this issue was
brought up (6f270e6bd8) since they shouldn't be needed anymore if the
order of the includes is the "correct" one. I also added a comment to
each affected include when this is inevitably encountered again in the
future.
Resolves: #32160
219 lines
6.7 KiB
C
219 lines
6.7 KiB
C
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
|
|
/* Make sure the net/if.h header is included before any linux/ one */
|
|
#include <net/if.h>
|
|
#include <errno.h>
|
|
#include <linux/if_arp.h>
|
|
#include <linux/if_vlan.h>
|
|
|
|
#include "parse-util.h"
|
|
#include "vlan-util.h"
|
|
#include "vlan.h"
|
|
|
|
static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *req) {
|
|
assert(link);
|
|
assert(req);
|
|
|
|
struct ifla_vlan_flags flags = {};
|
|
VLan *v = VLAN(netdev);
|
|
int r;
|
|
|
|
r = sd_netlink_message_append_u16(req, IFLA_VLAN_ID, v->id);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
if (v->protocol >= 0) {
|
|
r = sd_netlink_message_append_u16(req, IFLA_VLAN_PROTOCOL, htobe16(v->protocol));
|
|
if (r < 0)
|
|
return r;
|
|
}
|
|
|
|
if (v->gvrp != -1) {
|
|
flags.mask |= VLAN_FLAG_GVRP;
|
|
SET_FLAG(flags.flags, VLAN_FLAG_GVRP, v->gvrp);
|
|
}
|
|
|
|
if (v->mvrp != -1) {
|
|
flags.mask |= VLAN_FLAG_MVRP;
|
|
SET_FLAG(flags.flags, VLAN_FLAG_MVRP, v->mvrp);
|
|
}
|
|
|
|
if (v->reorder_hdr != -1) {
|
|
flags.mask |= VLAN_FLAG_REORDER_HDR;
|
|
SET_FLAG(flags.flags, VLAN_FLAG_REORDER_HDR, v->reorder_hdr);
|
|
}
|
|
|
|
if (v->loose_binding != -1) {
|
|
flags.mask |= VLAN_FLAG_LOOSE_BINDING;
|
|
SET_FLAG(flags.flags, VLAN_FLAG_LOOSE_BINDING, v->loose_binding);
|
|
}
|
|
|
|
r = sd_netlink_message_append_data(req, IFLA_VLAN_FLAGS, &flags, sizeof(struct ifla_vlan_flags));
|
|
if (r < 0)
|
|
return r;
|
|
|
|
if (!set_isempty(v->egress_qos_maps)) {
|
|
struct ifla_vlan_qos_mapping *m;
|
|
|
|
r = sd_netlink_message_open_container(req, IFLA_VLAN_EGRESS_QOS);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
SET_FOREACH(m, v->egress_qos_maps) {
|
|
r = sd_netlink_message_append_data(req, IFLA_VLAN_QOS_MAPPING, m, sizeof(struct ifla_vlan_qos_mapping));
|
|
if (r < 0)
|
|
return r;
|
|
}
|
|
|
|
r = sd_netlink_message_close_container(req);
|
|
if (r < 0)
|
|
return r;
|
|
}
|
|
|
|
if (!set_isempty(v->ingress_qos_maps)) {
|
|
struct ifla_vlan_qos_mapping *m;
|
|
|
|
r = sd_netlink_message_open_container(req, IFLA_VLAN_INGRESS_QOS);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
SET_FOREACH(m, v->ingress_qos_maps) {
|
|
r = sd_netlink_message_append_data(req, IFLA_VLAN_QOS_MAPPING, m, sizeof(struct ifla_vlan_qos_mapping));
|
|
if (r < 0)
|
|
return r;
|
|
}
|
|
|
|
r = sd_netlink_message_close_container(req);
|
|
if (r < 0)
|
|
return r;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void vlan_qos_maps_hash_func(const struct ifla_vlan_qos_mapping *x, struct siphash *state) {
|
|
siphash24_compress_typesafe(x->from, state);
|
|
siphash24_compress_typesafe(x->to, state);
|
|
}
|
|
|
|
static int vlan_qos_maps_compare_func(const struct ifla_vlan_qos_mapping *a, const struct ifla_vlan_qos_mapping *b) {
|
|
int r;
|
|
|
|
r = CMP(a->from, b->from);
|
|
if (r != 0)
|
|
return r;
|
|
|
|
return CMP(a->to, b->to);
|
|
}
|
|
|
|
DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
|
|
vlan_qos_maps_hash_ops,
|
|
struct ifla_vlan_qos_mapping,
|
|
vlan_qos_maps_hash_func,
|
|
vlan_qos_maps_compare_func,
|
|
free);
|
|
|
|
int config_parse_vlan_qos_maps(
|
|
const char *unit,
|
|
const char *filename,
|
|
unsigned line,
|
|
const char *section,
|
|
unsigned section_line,
|
|
const char *lvalue,
|
|
int ltype,
|
|
const char *rvalue,
|
|
void *data,
|
|
void *userdata) {
|
|
|
|
Set **s = ASSERT_PTR(data);
|
|
int r;
|
|
|
|
assert(filename);
|
|
assert(lvalue);
|
|
assert(rvalue);
|
|
|
|
if (isempty(rvalue)) {
|
|
*s = set_free(*s);
|
|
return 0;
|
|
}
|
|
|
|
for (const char *p = rvalue;;) {
|
|
_cleanup_free_ struct ifla_vlan_qos_mapping *m = NULL;
|
|
_cleanup_free_ char *w = NULL;
|
|
unsigned from, to;
|
|
|
|
r = extract_first_word(&p, &w, NULL, EXTRACT_CUNESCAPE|EXTRACT_UNQUOTE);
|
|
if (r == -ENOMEM)
|
|
return log_oom();
|
|
if (r < 0) {
|
|
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse %s, ignoring: %s", lvalue, rvalue);
|
|
return 0;
|
|
}
|
|
if (r == 0)
|
|
return 0;
|
|
|
|
r = parse_range(w, &from, &to);
|
|
if (r < 0) {
|
|
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse %s, ignoring: %s", lvalue, w);
|
|
continue;
|
|
}
|
|
|
|
m = new(struct ifla_vlan_qos_mapping, 1);
|
|
if (!m)
|
|
return log_oom();
|
|
|
|
*m = (struct ifla_vlan_qos_mapping) {
|
|
.from = from,
|
|
.to = to,
|
|
};
|
|
|
|
r = set_ensure_consume(s, &vlan_qos_maps_hash_ops, TAKE_PTR(m));
|
|
if (r < 0) {
|
|
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to store %s, ignoring: %s", lvalue, w);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
static int netdev_vlan_verify(NetDev *netdev, const char *filename) {
|
|
assert(filename);
|
|
|
|
VLan *v = VLAN(netdev);
|
|
|
|
if (v->id == VLANID_INVALID) {
|
|
log_netdev_warning(netdev, "VLAN without valid Id (%"PRIu16") configured in %s.", v->id, filename);
|
|
return -EINVAL;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void vlan_done(NetDev *netdev) {
|
|
VLan *v = VLAN(netdev);
|
|
|
|
set_free(v->egress_qos_maps);
|
|
set_free(v->ingress_qos_maps);
|
|
}
|
|
|
|
static void vlan_init(NetDev *netdev) {
|
|
VLan *v = VLAN(netdev);
|
|
|
|
v->id = VLANID_INVALID;
|
|
v->protocol = -1;
|
|
v->gvrp = -1;
|
|
v->mvrp = -1;
|
|
v->loose_binding = -1;
|
|
v->reorder_hdr = -1;
|
|
}
|
|
|
|
const NetDevVTable vlan_vtable = {
|
|
.object_size = sizeof(VLan),
|
|
.init = vlan_init,
|
|
.sections = NETDEV_COMMON_SECTIONS "VLAN\0",
|
|
.fill_message_create = netdev_vlan_fill_message_create,
|
|
.create_type = NETDEV_CREATE_STACKED,
|
|
.config_verify = netdev_vlan_verify,
|
|
.done = vlan_done,
|
|
.iftype = ARPHRD_ETHER,
|
|
};
|