Merge pull request #29224 from keszybz/netdev-config-parsing

Use a helper to simplify parsing of ranges in netdev config and related changes
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2023-09-22 14:29:47 +02:00 committed by GitHub
commit a0fe45a93f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 588 additions and 979 deletions

View file

@ -425,6 +425,21 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
return 0; return 0;
} }
int safe_atou_bounded(const char *s, unsigned min, unsigned max, unsigned *ret) {
unsigned v;
int r;
r = safe_atou(s, &v);
if (r < 0)
return r;
if (v < min || v > max)
return -ERANGE;
*ret = v;
return 0;
}
int safe_atoi(const char *s, int *ret_i) { int safe_atoi(const char *s, int *ret_i) {
unsigned base = 0; unsigned base = 0;
char *x = NULL; char *x = NULL;

View file

@ -30,11 +30,12 @@ int parse_fd(const char *t);
#define SAFE_ATO_MASK_FLAGS(base) ((base) & ~SAFE_ATO_ALL_FLAGS) #define SAFE_ATO_MASK_FLAGS(base) ((base) & ~SAFE_ATO_ALL_FLAGS)
int safe_atou_full(const char *s, unsigned base, unsigned *ret_u); int safe_atou_full(const char *s, unsigned base, unsigned *ret_u);
static inline int safe_atou(const char *s, unsigned *ret_u) { static inline int safe_atou(const char *s, unsigned *ret_u) {
return safe_atou_full(s, 0, ret_u); return safe_atou_full(s, 0, ret_u);
} }
int safe_atou_bounded(const char *s, unsigned min, unsigned max, unsigned *ret);
int safe_atoi(const char *s, int *ret_i); int safe_atoi(const char *s, int *ret_i);
int safe_atolli(const char *s, long long int *ret_i); int safe_atolli(const char *s, long long int *ret_i);

View file

@ -401,8 +401,8 @@ int sd_dhcp_client_set_client_id(
* the client-id. The caller is advised to account for that. */ * the client-id. The caller is advised to account for that. */
if ((type == ARPHRD_ETHER && data_len != ETH_ALEN) || if ((type == ARPHRD_ETHER && data_len != ETH_ALEN) ||
(type == ARPHRD_INFINIBAND && data_len != 8)) (type == ARPHRD_INFINIBAND && data_len != 8))
log_dhcp_client(client, "Changing client ID to hardware type %u with " log_dhcp_client(client,
"unexpected address length %zu", "Changing client ID to hardware type %u with unexpected address length %zu",
type, data_len); type, data_len);
client->client_id.type = type; client->client_id.type = type;
@ -1563,10 +1563,9 @@ static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer, size_
} }
r = dhcp_option_parse(offer, len, dhcp_lease_parse_options, lease, NULL); r = dhcp_option_parse(offer, len, dhcp_lease_parse_options, lease, NULL);
if (r != DHCP_OFFER) { if (r != DHCP_OFFER)
log_dhcp_client(client, "received message was not an OFFER, ignoring"); return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(ENOMSG),
return -ENOMSG; "received message was not an OFFER, ignoring");
}
lease->next_server = offer->siaddr; lease->next_server = offer->siaddr;
lease->address = offer->yiaddr; lease->address = offer->yiaddr;
@ -1576,19 +1575,16 @@ static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer, size_
if (lease->address == 0 || if (lease->address == 0 ||
lease->server_address == 0 || lease->server_address == 0 ||
lease->lifetime == 0) { lease->lifetime == 0)
log_dhcp_client(client, "received lease lacks address, server address or lease lifetime, ignoring"); return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(ENOMSG),
return -ENOMSG; "received lease lacks address, server address or lease lifetime, ignoring");
}
if (!lease->have_subnet_mask) { if (!lease->have_subnet_mask) {
r = dhcp_lease_set_default_subnet_mask(lease); r = dhcp_lease_set_default_subnet_mask(lease);
if (r < 0) { if (r < 0)
log_dhcp_client(client, return log_dhcp_client_errno(
"received lease lacks subnet mask, " client, SYNTHETIC_ERRNO(ENOMSG),
"and a fallback one cannot be generated, ignoring"); "received lease lacks subnet mask, and a fallback one cannot be generated, ignoring");
return -ENOMSG;
}
} }
sd_dhcp_lease_unref(client->lease); sd_dhcp_lease_unref(client->lease);
@ -1611,14 +1607,13 @@ static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force,
#if 0 #if 0
log_dhcp_client(client, "FORCERENEW"); log_dhcp_client(client, "FORCERENEW");
return 0; return 0;
#else #else
/* FIXME: Ignore FORCERENEW requests until we implement RFC3118 (Authentication for DHCP /* FIXME: Ignore FORCERENEW requests until we implement RFC3118 (Authentication for DHCP
* Messages) and/or RFC6704 (Forcerenew Nonce Authentication), as unauthenticated FORCERENEW * Messages) and/or RFC6704 (Forcerenew Nonce Authentication), as unauthenticated FORCERENEW
* requests causes a security issue (TALOS-2020-1142, CVE-2020-13529). */ * requests causes a security issue (TALOS-2020-1142, CVE-2020-13529). */
log_dhcp_client(client, "Received FORCERENEW, ignoring."); return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(ENOMSG),
return -ENOMSG; "Received FORCERENEW, ignoring.");
#endif #endif
} }
@ -1657,15 +1652,13 @@ static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack, size_t le
} }
r = dhcp_option_parse(ack, len, dhcp_lease_parse_options, lease, &error_message); r = dhcp_option_parse(ack, len, dhcp_lease_parse_options, lease, &error_message);
if (r == DHCP_NAK) { if (r == DHCP_NAK)
log_dhcp_client(client, "NAK: %s", strna(error_message)); return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(EADDRNOTAVAIL),
return -EADDRNOTAVAIL; "NAK: %s", strna(error_message));
}
if (r != DHCP_ACK) { if (r != DHCP_ACK)
log_dhcp_client(client, "received message was not an ACK, ignoring"); return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(ENOMSG),
return -ENOMSG; "received message was not an ACK, ignoring");
}
lease->next_server = ack->siaddr; lease->next_server = ack->siaddr;
@ -1673,20 +1666,16 @@ static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack, size_t le
if (lease->address == INADDR_ANY || if (lease->address == INADDR_ANY ||
lease->server_address == INADDR_ANY || lease->server_address == INADDR_ANY ||
lease->lifetime == 0) { lease->lifetime == 0)
log_dhcp_client(client, "received lease lacks address, server " return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(ENOMSG),
"address or lease lifetime, ignoring"); "received lease lacks address, server address or lease lifetime, ignoring");
return -ENOMSG;
}
if (lease->subnet_mask == INADDR_ANY) { if (lease->subnet_mask == INADDR_ANY) {
r = dhcp_lease_set_default_subnet_mask(lease); r = dhcp_lease_set_default_subnet_mask(lease);
if (r < 0) { if (r < 0)
log_dhcp_client(client, return log_dhcp_client_errno(
"received lease lacks subnet mask, " client, SYNTHETIC_ERRNO(ENOMSG),
"and a fallback one cannot be generated, ignoring"); "received lease lacks subnet mask, and a fallback one cannot be generated, ignoring");
return -ENOMSG;
}
} }
r = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE; r = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;

View file

@ -1141,7 +1141,8 @@ int sd_radv_pref64_prefix_set_prefix(
r = pref64_prefix_length_to_plc(prefixlen, &prefixlen_code); r = pref64_prefix_length_to_plc(prefixlen, &prefixlen_code);
if (r < 0) if (r < 0)
return log_radv_errno(NULL, r, "Unsupported PREF64 prefix length %u. Valid lengths are 32, 40, 48, 56, 64 and 96", prefixlen); return log_radv_errno(NULL, r,
"Unsupported PREF64 prefix length %u. Valid lengths are 32, 40, 48, 56, 64 and 96", prefixlen);
if (lifetime_usec > PREF64_MAX_LIFETIME_USEC) if (lifetime_usec > PREF64_MAX_LIFETIME_USEC)
return -EINVAL; return -EINVAL;

View file

@ -21,15 +21,10 @@ DEFINE_CONFIG_PARSE_ENUM(config_parse_bare_udp_iftype, bare_udp_protocol, BareUD
"Failed to parse EtherType="); "Failed to parse EtherType=");
static int netdev_bare_udp_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { static int netdev_bare_udp_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
BareUDP *u;
int r;
assert(netdev);
assert(m); assert(m);
u = BAREUDP(netdev); BareUDP *u = BAREUDP(netdev);
int r;
assert(u);
r = sd_netlink_message_append_u16(m, IFLA_BAREUDP_ETHERTYPE, htobe16(u->iftype)); r = sd_netlink_message_append_u16(m, IFLA_BAREUDP_ETHERTYPE, htobe16(u->iftype));
if (r < 0) if (r < 0)
@ -43,14 +38,9 @@ static int netdev_bare_udp_fill_message_create(NetDev *netdev, Link *link, sd_ne
} }
static int netdev_bare_udp_verify(NetDev *netdev, const char *filename) { static int netdev_bare_udp_verify(NetDev *netdev, const char *filename) {
BareUDP *u;
assert(netdev);
assert(filename); assert(filename);
u = BAREUDP(netdev); BareUDP *u = BAREUDP(netdev);
assert(u);
if (u->dest_port == 0) if (u->dest_port == 0)
return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL), return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
@ -64,13 +54,7 @@ static int netdev_bare_udp_verify(NetDev *netdev, const char *filename) {
} }
static void bare_udp_init(NetDev *netdev) { static void bare_udp_init(NetDev *netdev) {
BareUDP *u; BareUDP *u = BAREUDP(netdev);
assert(netdev);
u = BAREUDP(netdev);
assert(u);
u->iftype = _BARE_UDP_PROTOCOL_INVALID; u->iftype = _BARE_UDP_PROTOCOL_INVALID;
} }

View file

@ -16,9 +16,7 @@
#include "string-util.h" #include "string-util.h"
static void batadv_init(NetDev *n) { static void batadv_init(NetDev *n) {
BatmanAdvanced *b; BatmanAdvanced *b = BATADV(n);
b = BATADV(n);
/* Set defaults */ /* Set defaults */
b->aggregation = true; b->aggregation = true;
@ -115,11 +113,9 @@ static int netdev_batman_set_handler(sd_netlink *rtnl, sd_netlink_message *m, Ne
} }
static int netdev_batadv_post_create_message(NetDev *netdev, sd_netlink_message *message) { static int netdev_batadv_post_create_message(NetDev *netdev, sd_netlink_message *message) {
BatmanAdvanced *b; BatmanAdvanced *b = BATADV(netdev);
int r; int r;
assert_se(b = BATADV(netdev));
r = sd_netlink_message_append_u32(message, BATADV_ATTR_MESH_IFINDEX, netdev->ifindex); r = sd_netlink_message_append_u32(message, BATADV_ATTR_MESH_IFINDEX, netdev->ifindex);
if (r < 0) if (r < 0)
return r; return r;
@ -188,14 +184,10 @@ static int netdev_batadv_post_create(NetDev *netdev, Link *link) {
} }
static int netdev_batadv_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { static int netdev_batadv_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
BatmanAdvanced *b;
int r;
assert(netdev);
assert(m); assert(m);
b = BATADV(netdev); BatmanAdvanced *b = BATADV(netdev);
assert(b); int r;
r = sd_netlink_message_append_string(m, IFLA_BATADV_ALGO_NAME, batadv_routing_algorithm_kernel_to_string(b->routing_algorithm)); r = sd_netlink_message_append_string(m, IFLA_BATADV_ALGO_NAME, batadv_routing_algorithm_kernel_to_string(b->routing_algorithm));
if (r < 0) if (r < 0)

View file

@ -57,16 +57,11 @@ DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_arp_all_targets, bond_arp_all_targets
DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_primary_reselect, bond_primary_reselect, BondPrimaryReselect, "Failed to parse bond primary reselect"); DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_primary_reselect, bond_primary_reselect, BondPrimaryReselect, "Failed to parse bond primary reselect");
static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
Bond *b;
int r;
assert(netdev);
assert(!link); assert(!link);
assert(m); assert(m);
b = BOND(netdev); Bond *b = BOND(netdev);
int r;
assert(b);
if (b->mode != _NETDEV_BOND_MODE_INVALID) { if (b->mode != _NETDEV_BOND_MODE_INVALID) {
r = sd_netlink_message_append_u8(m, IFLA_BOND_MODE, b->mode); r = sd_netlink_message_append_u8(m, IFLA_BOND_MODE, b->mode);
@ -237,14 +232,14 @@ int config_parse_arp_ip_target_address(
void *data, void *data,
void *userdata) { void *userdata) {
Bond *b = userdata;
int r;
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
assert(data); assert(data);
Bond *b = BOND(userdata);
int r;
if (isempty(rvalue)) { if (isempty(rvalue)) {
b->arp_ip_targets = ordered_set_free(b->arp_ip_targets); b->arp_ip_targets = ordered_set_free(b->arp_ip_targets);
return 0; return 0;
@ -303,32 +298,18 @@ int config_parse_ad_actor_sys_prio(
const char *rvalue, const char *rvalue,
void *data, void *data,
void *userdata) { void *userdata) {
Bond *b = userdata;
uint16_t v;
int r;
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
assert(data); assert(data);
r = safe_atou16(rvalue, &v); Bond *b = ASSERT_PTR(userdata);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse actor system priority '%s', ignoring: %m", rvalue);
return 0;
}
if (v == 0) { return config_parse_uint16_bounded(
log_syntax(unit, LOG_WARNING, filename, line, 0, unit, filename, line, section, section_line, lvalue, rvalue,
"Failed to parse actor system priority '%s'. Range is [1,65535], ignoring.", 1, UINT16_MAX, true,
rvalue); &b->ad_actor_sys_prio);
return 0;
}
b->ad_actor_sys_prio = v;
return 0;
} }
int config_parse_ad_user_port_key( int config_parse_ad_user_port_key(
@ -342,31 +323,18 @@ int config_parse_ad_user_port_key(
const char *rvalue, const char *rvalue,
void *data, void *data,
void *userdata) { void *userdata) {
Bond *b = userdata;
uint16_t v;
int r;
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
assert(data); assert(data);
r = safe_atou16(rvalue, &v); Bond *b = ASSERT_PTR(userdata);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse user port key '%s', ignoring: %m", rvalue);
return 0;
}
if (v > 1023) { return config_parse_uint16_bounded(
log_syntax(unit, LOG_WARNING, filename, line, 0, unit, filename, line, section, section_line, lvalue, rvalue,
"Failed to parse user port key '%s'. Range is [0…1023], ignoring.", rvalue); 0, 1023, /* ignoring= */ true,
return 0; &b->ad_user_port_key);
}
b->ad_user_port_key = v;
return 0;
} }
int config_parse_ad_actor_system( int config_parse_ad_actor_system(
@ -409,23 +377,13 @@ int config_parse_ad_actor_system(
} }
static void bond_done(NetDev *netdev) { static void bond_done(NetDev *netdev) {
Bond *b; Bond *b = BOND(netdev);
assert(netdev);
b = BOND(netdev);
assert(b);
ordered_set_free(b->arp_ip_targets); ordered_set_free(b->arp_ip_targets);
} }
static void bond_init(NetDev *netdev) { static void bond_init(NetDev *netdev) {
Bond *b; Bond *b = BOND(netdev);
assert(netdev);
b = BOND(netdev);
assert(b);
b->mode = _NETDEV_BOND_MODE_INVALID; b->mode = _NETDEV_BOND_MODE_INVALID;
b->xmit_hash_policy = _NETDEV_BOND_XMIT_HASH_POLICY_INVALID; b->xmit_hash_policy = _NETDEV_BOND_XMIT_HASH_POLICY_INVALID;

View file

@ -46,11 +46,9 @@ static int netdev_bridge_set_handler(sd_netlink *rtnl, sd_netlink_message *m, Ne
} }
static int netdev_bridge_post_create_message(NetDev *netdev, sd_netlink_message *req) { static int netdev_bridge_post_create_message(NetDev *netdev, sd_netlink_message *req) {
Bridge *b; Bridge *b = BRIDGE(netdev);
int r; int r;
assert_se(b = BRIDGE(netdev));
r = sd_netlink_message_open_container(req, IFLA_LINKINFO); r = sd_netlink_message_open_container(req, IFLA_LINKINFO);
if (r < 0) if (r < 0)
return r; return r;
@ -189,36 +187,22 @@ int config_parse_bridge_igmp_version(
void *data, void *data,
void *userdata) { void *userdata) {
Bridge *b = userdata;
uint8_t u;
int r;
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
assert(data); assert(data);
Bridge *b = ASSERT_PTR(userdata);
if (isempty(rvalue)) { if (isempty(rvalue)) {
b->igmp_version = 0; /* 0 means unset. */ b->igmp_version = 0; /* 0 means unset. */
return 0; return 0;
} }
r = safe_atou8(rvalue, &u); return config_parse_uint8_bounded(
if (r < 0) { unit, filename, line, section, section_line, lvalue, rvalue,
log_syntax(unit, LOG_WARNING, filename, line, r, 2, 3, true,
"Failed to parse bridge's multicast IGMP version number '%s', ignoring assignment: %m", &b->igmp_version);
rvalue);
return 0;
}
if (!IN_SET(u, 2, 3)) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Invalid bridge's multicast IGMP version number '%s', ignoring assignment.", rvalue);
return 0;
}
b->igmp_version = u;
return 0;
} }
int config_parse_bridge_port_priority( int config_parse_bridge_port_priority(
@ -233,41 +217,20 @@ int config_parse_bridge_port_priority(
void *data, void *data,
void *userdata) { void *userdata) {
uint16_t i;
int r;
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
assert(data);
/* This is used in networkd-network-gperf.gperf. */ uint16_t *prio = ASSERT_PTR(data);
r = safe_atou16(rvalue, &i); return config_parse_uint16_bounded(
if (r < 0) { unit, filename, line, section, section_line, lvalue, rvalue,
log_syntax(unit, LOG_WARNING, filename, line, r, 0, LINK_BRIDGE_PORT_PRIORITY_MAX, true,
"Failed to parse bridge port priority, ignoring: %s", rvalue); prio);
return 0;
}
if (i > LINK_BRIDGE_PORT_PRIORITY_MAX) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Bridge port priority is larger than maximum %u, ignoring: %s",
LINK_BRIDGE_PORT_PRIORITY_MAX, rvalue);
return 0;
}
*((uint16_t *)data) = i;
return 0;
} }
static void bridge_init(NetDev *n) { static void bridge_init(NetDev *netdev) {
Bridge *b; Bridge *b = BRIDGE(netdev);
b = BRIDGE(n);
assert(b);
b->mcast_querier = -1; b->mcast_querier = -1;
b->mcast_snooping = -1; b->mcast_snooping = -1;

View file

@ -24,12 +24,10 @@ DEFINE_CONFIG_PARSE_ENUM(config_parse_fou_encap_type, fou_encap_type, FooOverUDP
"Failed to parse Encapsulation="); "Failed to parse Encapsulation=");
static int netdev_fill_fou_tunnel_message(NetDev *netdev, sd_netlink_message *m) { static int netdev_fill_fou_tunnel_message(NetDev *netdev, sd_netlink_message *m) {
FouTunnel *t; FouTunnel *t = FOU(netdev);
uint8_t encap_type; uint8_t encap_type;
int r; int r;
assert_se(t = FOU(netdev));
r = sd_netlink_message_append_u16(m, FOU_ATTR_PORT, htobe16(t->port)); r = sd_netlink_message_append_u16(m, FOU_ATTR_PORT, htobe16(t->port));
if (r < 0) if (r < 0)
return r; return r;
@ -128,7 +126,6 @@ static int netdev_fou_tunnel_create(NetDev *netdev) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r; int r;
assert(netdev);
assert(FOU(netdev)); assert(FOU(netdev));
r = netdev_create_fou_tunnel_message(netdev, &m); r = netdev_create_fou_tunnel_message(netdev, &m);
@ -156,37 +153,32 @@ int config_parse_ip_protocol(
void *data, void *data,
void *userdata) { void *userdata) {
uint8_t *ret = ASSERT_PTR(data);
unsigned protocol;
/* linux/fou.h defines the netlink field as one byte, so we need to reject protocols numbers that
* don't fit in one byte. */
int r;
assert(filename); assert(filename);
assert(section); assert(section);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
r = parse_ip_protocol(rvalue); uint8_t *proto = ASSERT_PTR(data);
if (r >= 0) int r;
protocol = r;
else { r = parse_ip_protocol_full(rvalue, /* relaxed= */ true);
r = safe_atou(rvalue, &protocol); if (r < 0) {
if (r < 0) log_syntax(unit, LOG_WARNING, filename, line, r,
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse '%s=%s', ignoring: %m",
"Failed to parse IP protocol '%s' for FooOverUDP tunnel, " lvalue, rvalue);
"ignoring assignment: %m", rvalue);
return 0; return 0;
} }
if (protocol > UINT8_MAX) { if (r > UINT8_MAX) {
log_syntax(unit, LOG_WARNING, filename, line, 0, /* linux/fou.h defines the netlink field as one byte, so we need to reject
"IP protocol '%s' for FooOverUDP tunnel out of range, " * protocols numbers that don't fit in one byte. */
"ignoring assignment: %m", rvalue); log_syntax(unit, LOG_WARNING, filename, line, r,
"Invalid '%s=%s', allowed range is 0..255, ignoring.",
lvalue, rvalue);
return 0; return 0;
} }
*ret = protocol; *proto = r;
return 0; return 0;
} }
@ -225,14 +217,9 @@ int config_parse_fou_tunnel_address(
} }
static int netdev_fou_tunnel_verify(NetDev *netdev, const char *filename) { static int netdev_fou_tunnel_verify(NetDev *netdev, const char *filename) {
FouTunnel *t;
assert(netdev);
assert(filename); assert(filename);
t = FOU(netdev); FouTunnel *t = FOU(netdev);
assert(t);
switch (t->fou_encap_type) { switch (t->fou_encap_type) {
case NETDEV_FOO_OVER_UDP_ENCAP_DIRECT: case NETDEV_FOO_OVER_UDP_ENCAP_DIRECT:
@ -263,13 +250,7 @@ static int netdev_fou_tunnel_verify(NetDev *netdev, const char *filename) {
} }
static void fou_tunnel_init(NetDev *netdev) { static void fou_tunnel_init(NetDev *netdev) {
FouTunnel *t; FouTunnel *t = FOU(netdev);
assert(netdev);
t = FOU(netdev);
assert(t);
t->fou_encap_type = NETDEV_FOO_OVER_UDP_ENCAP_DIRECT; t->fou_encap_type = NETDEV_FOO_OVER_UDP_ENCAP_DIRECT;
} }

View file

@ -19,8 +19,8 @@
#define DEFAULT_GENEVE_DESTINATION_PORT 6081 #define DEFAULT_GENEVE_DESTINATION_PORT 6081
static const char* const geneve_df_table[_NETDEV_GENEVE_DF_MAX] = { static const char* const geneve_df_table[_NETDEV_GENEVE_DF_MAX] = {
[NETDEV_GENEVE_DF_NO] = "no", [NETDEV_GENEVE_DF_NO] = "no",
[NETDEV_GENEVE_DF_YES] = "yes", [NETDEV_GENEVE_DF_YES] = "yes",
[NETDEV_GENEVE_DF_INHERIT] = "inherit", [NETDEV_GENEVE_DF_INHERIT] = "inherit",
}; };
@ -28,13 +28,10 @@ DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(geneve_df, GeneveDF, NETDEV_GENEVE_DF_YE
DEFINE_CONFIG_PARSE_ENUM(config_parse_geneve_df, geneve_df, GeneveDF, "Failed to parse Geneve IPDoNotFragment= setting"); DEFINE_CONFIG_PARSE_ENUM(config_parse_geneve_df, geneve_df, GeneveDF, "Failed to parse Geneve IPDoNotFragment= setting");
static int netdev_geneve_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { static int netdev_geneve_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
Geneve *v;
int r;
assert(netdev);
assert(m); assert(m);
v = GENEVE(netdev); Geneve *v = GENEVE(netdev);
int r;
if (v->id <= GENEVE_VID_MAX) { if (v->id <= GENEVE_VID_MAX) {
r = sd_netlink_message_append_u32(m, IFLA_GENEVE_ID, v->id); r = sd_netlink_message_append_u32(m, IFLA_GENEVE_ID, v->id);
@ -116,29 +113,17 @@ int config_parse_geneve_vni(
void *data, void *data,
void *userdata) { void *userdata) {
Geneve *v = userdata;
uint32_t f;
int r;
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
assert(data); assert(data);
r = safe_atou32(rvalue, &f); Geneve *v = ASSERT_PTR(userdata);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse Geneve VNI '%s'.", rvalue);
return 0;
}
if (f > GENEVE_VID_MAX){ return config_parse_uint32_bounded(
log_syntax(unit, LOG_WARNING, filename, line, 0, "Geneve VNI out is of range '%s'.", rvalue); unit, filename, line, section, section_line, lvalue, rvalue,
return 0; 0, GENEVE_VID_MAX, true,
} &v->id);
v->id = f;
return 0;
} }
int config_parse_geneve_address( int config_parse_geneve_address(
@ -153,24 +138,26 @@ int config_parse_geneve_address(
void *data, void *data,
void *userdata) { void *userdata) {
Geneve *v = userdata;
union in_addr_union *addr = data, buffer;
int r, f;
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
assert(data); assert(data);
Geneve *v = ASSERT_PTR(userdata);
union in_addr_union *addr = data, buffer;
int r, f;
r = in_addr_from_string_auto(rvalue, &f, &buffer); r = in_addr_from_string_auto(rvalue, &f, &buffer);
if (r < 0) { if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "geneve '%s' address is invalid, ignoring assignment: %s", lvalue, rvalue); log_syntax(unit, LOG_WARNING, filename, line, r,
"geneve '%s' address is invalid, ignoring assignment: %s", lvalue, rvalue);
return 0; return 0;
} }
r = in_addr_is_multicast(f, &buffer); r = in_addr_is_multicast(f, &buffer);
if (r > 0) { if (r > 0) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "geneve invalid multicast '%s' address, ignoring assignment: %s", lvalue, rvalue); log_syntax(unit, LOG_WARNING, filename, line, 0,
"geneve invalid multicast '%s' address, ignoring assignment: %s", lvalue, rvalue);
return 0; return 0;
} }
@ -192,15 +179,15 @@ int config_parse_geneve_flow_label(
void *data, void *data,
void *userdata) { void *userdata) {
Geneve *v = userdata;
uint32_t f;
int r;
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
assert(data); assert(data);
Geneve *v = ASSERT_PTR(userdata);
uint32_t f;
int r;
r = safe_atou32(rvalue, &f); r = safe_atou32(rvalue, &f);
if (r < 0) { if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse Geneve flow label '%s'.", rvalue); log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse Geneve flow label '%s'.", rvalue);
@ -230,60 +217,44 @@ int config_parse_geneve_ttl(
void *data, void *data,
void *userdata) { void *userdata) {
Geneve *v = userdata;
unsigned f;
int r;
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
assert(data); assert(data);
if (streq(rvalue, "inherit")) Geneve *v = ASSERT_PTR(userdata);
int r;
if (streq(rvalue, "inherit")) {
v->inherit = true; v->inherit = true;
else { v->ttl = 0; /* unset the unused ttl field for clarity */
r = safe_atou(rvalue, &f); return 0;
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse Geneve TTL '%s', ignoring assignment: %m", rvalue);
return 0;
}
if (f > 255) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Invalid Geneve TTL '%s'. TTL must be <= 255. Ignoring assignment.", rvalue);
return 0;
}
v->ttl = f;
} }
r = config_parse_uint8_bounded(
unit, filename, line, section, section_line, lvalue, rvalue,
0, UINT8_MAX, true,
&v->ttl);
if (r <= 0)
return r;
v->inherit = false;
return 0; return 0;
} }
static int netdev_geneve_verify(NetDev *netdev, const char *filename) { static int netdev_geneve_verify(NetDev *netdev, const char *filename) {
Geneve *v = GENEVE(netdev);
assert(netdev);
assert(v);
assert(filename); assert(filename);
Geneve *v = GENEVE(netdev);
if (v->id > GENEVE_VID_MAX) if (v->id > GENEVE_VID_MAX)
return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL), return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
"%s: Geneve without valid VNI (or Virtual Network Identifier) configured. Ignoring.", "%s: Geneve without valid VNI (or Virtual Network Identifier) configured. Ignoring.",
filename); filename);
return 0; return 0;
} }
static void geneve_init(NetDev *netdev) { static void geneve_init(NetDev *netdev) {
Geneve *v; Geneve *v = GENEVE(netdev);
assert(netdev);
v = GENEVE(netdev);
assert(v);
v->id = GENEVE_VID_MAX + 1; v->id = GENEVE_VID_MAX + 1;
v->geneve_df = _NETDEV_GENEVE_DF_INVALID; v->geneve_df = _NETDEV_GENEVE_DF_INVALID;

View file

@ -12,29 +12,18 @@ assert_cc((int) IP_OVER_INFINIBAND_MODE_DATAGRAM == (int) IPOIB_MODE_DATAGRAM);
assert_cc((int) IP_OVER_INFINIBAND_MODE_CONNECTED == (int) IPOIB_MODE_CONNECTED); assert_cc((int) IP_OVER_INFINIBAND_MODE_CONNECTED == (int) IPOIB_MODE_CONNECTED);
static void netdev_ipoib_init(NetDev *netdev) { static void netdev_ipoib_init(NetDev *netdev) {
IPoIB *ipoib; IPoIB *ipoib = IPOIB(netdev);
assert(netdev);
ipoib = IPOIB(netdev);
assert(ipoib);
ipoib->mode = _IP_OVER_INFINIBAND_MODE_INVALID; ipoib->mode = _IP_OVER_INFINIBAND_MODE_INVALID;
ipoib->umcast = -1; ipoib->umcast = -1;
} }
static int netdev_ipoib_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { static int netdev_ipoib_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
IPoIB *ipoib;
int r;
assert(netdev);
assert(link); assert(link);
assert(m); assert(m);
ipoib = IPOIB(netdev); IPoIB *ipoib = IPOIB(netdev);
int r;
assert(ipoib);
if (ipoib->pkey > 0) { if (ipoib->pkey > 0) {
r = sd_netlink_message_append_u16(m, IFLA_IPOIB_PKEY, ipoib->pkey); r = sd_netlink_message_append_u16(m, IFLA_IPOIB_PKEY, ipoib->pkey);

View file

@ -14,19 +14,12 @@ DEFINE_CONFIG_PARSE_ENUM(config_parse_ipvlan_mode, ipvlan_mode, IPVlanMode, "Fai
DEFINE_CONFIG_PARSE_ENUM(config_parse_ipvlan_flags, ipvlan_flags, IPVlanFlags, "Failed to parse ipvlan flags"); DEFINE_CONFIG_PARSE_ENUM(config_parse_ipvlan_flags, ipvlan_flags, IPVlanFlags, "Failed to parse ipvlan flags");
static int netdev_ipvlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *req) { static int netdev_ipvlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *req) {
IPVlan *m;
int r;
assert(netdev); assert(netdev);
assert(link); assert(link);
assert(netdev->ifname); assert(netdev->ifname);
if (netdev->kind == NETDEV_KIND_IPVLAN) IPVlan *m = netdev->kind == NETDEV_KIND_IPVLAN ? IPVLAN(netdev) : IPVTAP(netdev);
m = IPVLAN(netdev); int r;
else
m = IPVTAP(netdev);
assert(m);
if (m->mode != _NETDEV_IPVLAN_MODE_INVALID) { if (m->mode != _NETDEV_IPVLAN_MODE_INVALID) {
r = sd_netlink_message_append_u16(req, IFLA_IPVLAN_MODE, m->mode); r = sd_netlink_message_append_u16(req, IFLA_IPVLAN_MODE, m->mode);
@ -43,17 +36,8 @@ static int netdev_ipvlan_fill_message_create(NetDev *netdev, Link *link, sd_netl
return 0; return 0;
} }
static void ipvlan_init(NetDev *n) { static void ipvlan_init(NetDev *netdev) {
IPVlan *m; IPVlan *m = ASSERT_PTR(netdev)->kind == NETDEV_KIND_IPVLAN ? IPVLAN(netdev) : IPVTAP(netdev);
assert(n);
if (n->kind == NETDEV_KIND_IPVLAN)
m = IPVLAN(n);
else
m = IPVTAP(n);
assert(m);
m->mode = _NETDEV_IPVLAN_MODE_INVALID; m->mode = _NETDEV_IPVLAN_MODE_INVALID;
m->flags = _NETDEV_IPVLAN_FLAGS_INVALID; m->flags = _NETDEV_IPVLAN_FLAGS_INVALID;
@ -80,13 +64,10 @@ const NetDevVTable ipvtap_vtable = {
}; };
IPVlanMode link_get_ipvlan_mode(Link *link) { IPVlanMode link_get_ipvlan_mode(Link *link) {
IPVlan *ipvlan;
assert(link); assert(link);
ipvlan = IPVLAN(link->netdev); if (!link->netdev || link->netdev->kind != NETDEV_KIND_IPVLAN)
if (!ipvlan)
return _NETDEV_IPVLAN_MODE_INVALID; return _NETDEV_IPVLAN_MODE_INVALID;
return ipvlan->mode; return IPVLAN(link->netdev)->mode;
} }

View file

@ -92,15 +92,13 @@ static int l2tp_session_new_static(L2tpTunnel *t, const char *filename, unsigned
} }
static int netdev_l2tp_create_message_tunnel(NetDev *netdev, union in_addr_union *local_address, sd_netlink_message **ret) { static int netdev_l2tp_create_message_tunnel(NetDev *netdev, union in_addr_union *local_address, sd_netlink_message **ret) {
assert(local_address);
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
uint16_t encap_type; uint16_t encap_type;
L2tpTunnel *t; L2tpTunnel *t = L2TP(netdev);
int r; int r;
assert(netdev);
assert(local_address);
assert_se(t = L2TP(netdev));
r = sd_genl_message_new(netdev->manager->genl, L2TP_GENL_NAME, L2TP_CMD_TUNNEL_CREATE, &m); r = sd_genl_message_new(netdev->manager->genl, L2TP_GENL_NAME, L2TP_CMD_TUNNEL_CREATE, &m);
if (r < 0) if (r < 0)
return r; return r;
@ -278,13 +276,11 @@ static int link_get_l2tp_local_address(Link *link, L2tpTunnel *t, union in_addr_
static int l2tp_get_local_address(NetDev *netdev, union in_addr_union *ret) { static int l2tp_get_local_address(NetDev *netdev, union in_addr_union *ret) {
Link *link = NULL; Link *link = NULL;
L2tpTunnel *t; L2tpTunnel *t = L2TP(netdev);
Address *a = NULL; Address *a = NULL;
int r; int r;
assert(netdev);
assert(netdev->manager); assert(netdev->manager);
assert_se(t = L2TP(netdev));
if (t->local_ifname) { if (t->local_ifname) {
r = link_get_by_name(netdev->manager, t->local_ifname, &link); r = link_get_by_name(netdev->manager, t->local_ifname, &link);
@ -403,16 +399,11 @@ static int l2tp_create_session(NetDev *netdev, L2tpSession *session) {
static int l2tp_create_tunnel_handler(sd_netlink *rtnl, sd_netlink_message *m, NetDev *netdev) { static int l2tp_create_tunnel_handler(sd_netlink *rtnl, sd_netlink_message *m, NetDev *netdev) {
L2tpSession *session; L2tpSession *session;
L2tpTunnel *t; L2tpTunnel *t = L2TP(netdev);
int r; int r;
assert(netdev);
assert(netdev->state != _NETDEV_STATE_INVALID); assert(netdev->state != _NETDEV_STATE_INVALID);
t = L2TP(netdev);
assert(t);
r = sd_netlink_message_get_errno(m); r = sd_netlink_message_get_errno(m);
if (r == -EEXIST) if (r == -EEXIST)
log_netdev_info(netdev, "netdev exists, using existing without changing its parameters"); log_netdev_info(netdev, "netdev exists, using existing without changing its parameters");
@ -434,12 +425,9 @@ static int l2tp_create_tunnel_handler(sd_netlink *rtnl, sd_netlink_message *m, N
static int l2tp_create_tunnel(NetDev *netdev) { static int l2tp_create_tunnel(NetDev *netdev) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
union in_addr_union local_address; union in_addr_union local_address;
L2tpTunnel *t; L2tpTunnel *t = L2TP(netdev);
int r; int r;
assert(netdev);
assert_se(t = L2TP(netdev));
r = l2tp_get_local_address(netdev, &local_address); r = l2tp_get_local_address(netdev, &local_address);
if (r < 0) if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not find local address."); return log_netdev_error_errno(netdev, r, "Could not find local address.");
@ -626,30 +614,16 @@ int config_parse_l2tp_tunnel_id(
void *data, void *data,
void *userdata) { void *userdata) {
uint32_t *id = data, k;
int r;
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
assert(data);
r = safe_atou32(rvalue, &k); uint32_t *id = ASSERT_PTR(data);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse L2TP tunnel id. Ignoring assignment: %s", rvalue);
return 0;
}
if (k == 0) { return config_parse_uint32_bounded(
log_syntax(unit, LOG_WARNING, filename, line, 0, unit, filename, line, section, section_line, lvalue, rvalue,
"Invalid L2TP tunnel id. Ignoring assignment: %s", rvalue); 1, UINT32_MAX, true,
return 0; id);
}
*id = k;
return 0;
} }
int config_parse_l2tp_session_id( int config_parse_l2tp_session_id(
@ -664,40 +638,29 @@ int config_parse_l2tp_session_id(
void *data, void *data,
void *userdata) { void *userdata) {
_cleanup_(l2tp_session_free_or_set_invalidp) L2tpSession *session = NULL;
L2tpTunnel *t = userdata;
uint32_t k;
int r;
assert(filename); assert(filename);
assert(section); assert(section);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
assert(data); assert(data);
L2tpTunnel *t = ASSERT_PTR(userdata);
_cleanup_(l2tp_session_free_or_set_invalidp) L2tpSession *session = NULL;
int r;
r = l2tp_session_new_static(t, filename, section_line, &session); r = l2tp_session_new_static(t, filename, section_line, &session);
if (r < 0) if (r < 0)
return log_oom(); return log_oom();
r = safe_atou32(rvalue, &k); uint32_t *id = streq(lvalue, "SessionId") ? &session->session_id : &session->peer_session_id;
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse L2TP session id. Ignoring assignment: %s", rvalue);
return 0;
}
if (k == 0) { r = config_parse_uint32_bounded(
log_syntax(unit, LOG_WARNING, filename, line, 0, unit, filename, line, section, section_line, lvalue, rvalue,
"Invalid L2TP session id. Ignoring assignment: %s", rvalue); 1, UINT32_MAX, true,
return 0; id);
} if (r <= 0)
return r;
if (streq(lvalue, "SessionId")) TAKE_PTR(session);
session->session_id = k;
else
session->peer_session_id = k;
session = NULL;
return 0; return 0;
} }
@ -782,13 +745,7 @@ int config_parse_l2tp_session_name(
} }
static void l2tp_tunnel_init(NetDev *netdev) { static void l2tp_tunnel_init(NetDev *netdev) {
L2tpTunnel *t; L2tpTunnel *t = L2TP(netdev);
assert(netdev);
t = L2TP(netdev);
assert(t);
t->l2tp_encap_type = NETDEV_L2TP_ENCAPTYPE_UDP; t->l2tp_encap_type = NETDEV_L2TP_ENCAPTYPE_UDP;
t->udp6_csum_rx = true; t->udp6_csum_rx = true;
@ -822,15 +779,10 @@ static int l2tp_session_verify(L2tpSession *session) {
} }
static int netdev_l2tp_tunnel_verify(NetDev *netdev, const char *filename) { static int netdev_l2tp_tunnel_verify(NetDev *netdev, const char *filename) {
L2tpTunnel *t;
L2tpSession *session;
assert(netdev);
assert(filename); assert(filename);
t = L2TP(netdev); L2tpTunnel *t = L2TP(netdev);
L2tpSession *session;
assert(t);
if (!IN_SET(t->family, AF_INET, AF_INET6)) if (!IN_SET(t->family, AF_INET, AF_INET6))
return log_netdev_error_errno(netdev, SYNTHETIC_ERRNO(EINVAL), return log_netdev_error_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
@ -855,13 +807,7 @@ static int netdev_l2tp_tunnel_verify(NetDev *netdev, const char *filename) {
} }
static void l2tp_tunnel_done(NetDev *netdev) { static void l2tp_tunnel_done(NetDev *netdev) {
L2tpTunnel *t; L2tpTunnel *t = L2TP(netdev);
assert(netdev);
t = L2TP(netdev);
assert(t);
ordered_hashmap_free_with_destructor(t->sessions_by_section, l2tp_session_free); ordered_hashmap_free_with_destructor(t->sessions_by_section, l2tp_session_free);
free(t->local_ifname); free(t->local_ifname);

View file

@ -356,13 +356,11 @@ static int netdev_macsec_configure_receive_association(NetDev *netdev, ReceiveAs
} }
static int macsec_receive_channel_handler(sd_netlink *rtnl, sd_netlink_message *m, ReceiveChannel *c) { static int macsec_receive_channel_handler(sd_netlink *rtnl, sd_netlink_message *m, ReceiveChannel *c) {
NetDev *netdev;
int r;
assert(c); assert(c);
assert(c->macsec); assert(c->macsec);
netdev = NETDEV(c->macsec); NetDev *netdev = ASSERT_PTR(NETDEV(c->macsec));
int r;
assert(netdev->state != _NETDEV_STATE_INVALID); assert(netdev->state != _NETDEV_STATE_INVALID);
@ -474,15 +472,11 @@ static int netdev_macsec_configure_transmit_association(NetDev *netdev, Transmit
} }
static int netdev_macsec_configure(NetDev *netdev, Link *link) { static int netdev_macsec_configure(NetDev *netdev, Link *link) {
MACsec *s = MACSEC(netdev);
TransmitAssociation *a; TransmitAssociation *a;
ReceiveChannel *c; ReceiveChannel *c;
MACsec *s;
int r; int r;
assert(netdev);
s = MACSEC(netdev);
assert(s);
ORDERED_HASHMAP_FOREACH(a, s->transmit_associations_by_section) { ORDERED_HASHMAP_FOREACH(a, s->transmit_associations_by_section) {
r = netdev_macsec_configure_transmit_association(netdev, a); r = netdev_macsec_configure_transmit_association(netdev, a);
if (r < 0) if (r < 0)
@ -499,15 +493,10 @@ static int netdev_macsec_configure(NetDev *netdev, Link *link) {
} }
static int netdev_macsec_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { static int netdev_macsec_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
MACsec *v;
int r;
assert(netdev);
assert(m); assert(m);
v = MACSEC(netdev); MACsec *v = MACSEC(netdev);
int r;
assert(v);
if (v->port > 0) { if (v->port > 0) {
r = sd_netlink_message_append_u16(m, IFLA_MACSEC_PORT, v->port); r = sd_netlink_message_append_u16(m, IFLA_MACSEC_PORT, v->port);
@ -540,19 +529,19 @@ int config_parse_macsec_port(
void *data, void *data,
void *userdata) { void *userdata) {
_cleanup_(macsec_receive_association_free_or_set_invalidp) ReceiveAssociation *b = NULL;
_cleanup_(macsec_receive_channel_free_or_set_invalidp) ReceiveChannel *c = NULL;
MACsec *s = userdata;
uint16_t port;
void *dest;
int r;
assert(filename); assert(filename);
assert(section); assert(section);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
assert(data); assert(data);
MACsec *s = ASSERT_PTR(userdata);
_cleanup_(macsec_receive_association_free_or_set_invalidp) ReceiveAssociation *b = NULL;
_cleanup_(macsec_receive_channel_free_or_set_invalidp) ReceiveChannel *c = NULL;
uint16_t port;
void *dest;
int r;
/* This parses port used to make Secure Channel Identifier (SCI) */ /* This parses port used to make Secure Channel Identifier (SCI) */
if (streq(section, "MACsec")) if (streq(section, "MACsec"))
@ -601,17 +590,17 @@ int config_parse_macsec_hw_address(
void *data, void *data,
void *userdata) { void *userdata) {
_cleanup_(macsec_receive_association_free_or_set_invalidp) ReceiveAssociation *b = NULL;
_cleanup_(macsec_receive_channel_free_or_set_invalidp) ReceiveChannel *c = NULL;
MACsec *s = userdata;
int r;
assert(filename); assert(filename);
assert(section); assert(section);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
assert(data); assert(data);
MACsec *s = ASSERT_PTR(userdata);
_cleanup_(macsec_receive_association_free_or_set_invalidp) ReceiveAssociation *b = NULL;
_cleanup_(macsec_receive_channel_free_or_set_invalidp) ReceiveChannel *c = NULL;
int r;
if (streq(section, "MACsecReceiveChannel")) if (streq(section, "MACsecReceiveChannel"))
r = macsec_receive_channel_new_static(s, filename, section_line, &c); r = macsec_receive_channel_new_static(s, filename, section_line, &c);
else else
@ -645,18 +634,18 @@ int config_parse_macsec_packet_number(
void *data, void *data,
void *userdata) { void *userdata) {
_cleanup_(macsec_transmit_association_free_or_set_invalidp) TransmitAssociation *a = NULL;
_cleanup_(macsec_receive_association_free_or_set_invalidp) ReceiveAssociation *b = NULL;
MACsec *s = userdata;
uint32_t val, *dest;
int r;
assert(filename); assert(filename);
assert(section); assert(section);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
assert(data); assert(data);
MACsec *s = ASSERT_PTR(userdata);
_cleanup_(macsec_transmit_association_free_or_set_invalidp) TransmitAssociation *a = NULL;
_cleanup_(macsec_receive_association_free_or_set_invalidp) ReceiveAssociation *b = NULL;
uint32_t val, *dest;
int r;
if (streq(section, "MACsecTransmitAssociation")) if (streq(section, "MACsecTransmitAssociation"))
r = macsec_transmit_association_new_static(s, filename, section_line, &a); r = macsec_transmit_association_new_static(s, filename, section_line, &a);
else else
@ -1126,6 +1115,8 @@ static int macsec_receive_association_verify(ReceiveAssociation *a) {
} }
static int netdev_macsec_verify(NetDev *netdev, const char *filename) { static int netdev_macsec_verify(NetDev *netdev, const char *filename) {
assert(filename);
MACsec *v = MACSEC(netdev); MACsec *v = MACSEC(netdev);
TransmitAssociation *a; TransmitAssociation *a;
ReceiveAssociation *n; ReceiveAssociation *n;
@ -1134,10 +1125,6 @@ static int netdev_macsec_verify(NetDev *netdev, const char *filename) {
bool use_for_encoding; bool use_for_encoding;
int r; int r;
assert(netdev);
assert(v);
assert(filename);
ORDERED_HASHMAP_FOREACH(c, v->receive_channels_by_section) { ORDERED_HASHMAP_FOREACH(c, v->receive_channels_by_section) {
r = macsec_receive_channel_verify(c); r = macsec_receive_channel_verify(c);
if (r < 0) if (r < 0)
@ -1192,30 +1179,18 @@ static int netdev_macsec_verify(NetDev *netdev, const char *filename) {
} }
static void macsec_init(NetDev *netdev) { static void macsec_init(NetDev *netdev) {
MACsec *v; MACsec *v = MACSEC(netdev);
assert(netdev);
v = MACSEC(netdev);
assert(v);
v->encrypt = -1; v->encrypt = -1;
} }
static void macsec_done(NetDev *netdev) { static void macsec_done(NetDev *netdev) {
MACsec *t; MACsec *v = MACSEC(netdev);
assert(netdev); ordered_hashmap_free_with_destructor(v->receive_channels, macsec_receive_channel_free);
ordered_hashmap_free_with_destructor(v->receive_channels_by_section, macsec_receive_channel_free);
t = MACSEC(netdev); ordered_hashmap_free_with_destructor(v->transmit_associations_by_section, macsec_transmit_association_free);
ordered_hashmap_free_with_destructor(v->receive_associations_by_section, macsec_receive_association_free);
assert(t);
ordered_hashmap_free_with_destructor(t->receive_channels, macsec_receive_channel_free);
ordered_hashmap_free_with_destructor(t->receive_channels_by_section, macsec_receive_channel_free);
ordered_hashmap_free_with_destructor(t->transmit_associations_by_section, macsec_transmit_association_free);
ordered_hashmap_free_with_destructor(t->receive_associations_by_section, macsec_receive_association_free);
} }
const NetDevVTable macsec_vtable = { const NetDevVTable macsec_vtable = {

View file

@ -13,20 +13,13 @@
DEFINE_CONFIG_PARSE_ENUM(config_parse_macvlan_mode, macvlan_mode, MacVlanMode, "Failed to parse macvlan mode"); DEFINE_CONFIG_PARSE_ENUM(config_parse_macvlan_mode, macvlan_mode, MacVlanMode, "Failed to parse macvlan mode");
static int netdev_macvlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *req) { static int netdev_macvlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *req) {
MacVlan *m;
int r;
assert(netdev); assert(netdev);
assert(link);
assert(netdev->ifname); assert(netdev->ifname);
assert(link);
assert(link->network); assert(link->network);
if (netdev->kind == NETDEV_KIND_MACVLAN) MacVlan *m = netdev->kind == NETDEV_KIND_MACVLAN ? MACVLAN(netdev) : MACVTAP(netdev);
m = MACVLAN(netdev); int r;
else
m = MACVTAP(netdev);
assert(m);
if (m->mode == NETDEV_MACVLAN_MODE_SOURCE && !set_isempty(m->match_source_mac)) { if (m->mode == NETDEV_MACVLAN_MODE_SOURCE && !set_isempty(m->match_source_mac)) {
const struct ether_addr *mac_addr; const struct ether_addr *mac_addr;
@ -84,64 +77,33 @@ int config_parse_macvlan_broadcast_queue_size(
void *data, void *data,
void *userdata) { void *userdata) {
MacVlan *m = ASSERT_PTR(userdata);
uint32_t v;
int r;
assert(filename); assert(filename);
assert(section); assert(section);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
assert(data); assert(data);
MacVlan *m = ASSERT_PTR(userdata);
if (isempty(rvalue)) { if (isempty(rvalue)) {
m->bc_queue_length = UINT32_MAX; m->bc_queue_length = UINT32_MAX;
return 0; return 0;
} }
r = safe_atou32(rvalue, &v); return config_parse_uint32_bounded(
if (r < 0) { unit, filename, line, section, section_line, lvalue, rvalue,
log_syntax(unit, LOG_WARNING, filename, line, r, 0, UINT32_MAX - 1, true,
"Failed to parse BroadcastMulticastQueueLength=%s, ignoring assignment: %m", rvalue); &m->bc_queue_length);
return 0;
}
if (v == UINT32_MAX) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Invalid BroadcastMulticastQueueLength=%s, ignoring assignment: %m", rvalue);
return 0;
}
m->bc_queue_length = v;
return 0;
} }
static void macvlan_done(NetDev *n) { static void macvlan_done(NetDev *netdev) {
MacVlan *m; MacVlan *m = ASSERT_PTR(netdev)->kind == NETDEV_KIND_MACVLAN ? MACVLAN(netdev) : MACVTAP(netdev);
assert(n);
if (n->kind == NETDEV_KIND_MACVLAN)
m = MACVLAN(n);
else
m = MACVTAP(n);
assert(m);
set_free(m->match_source_mac); set_free(m->match_source_mac);
} }
static void macvlan_init(NetDev *n) { static void macvlan_init(NetDev *netdev) {
MacVlan *m; MacVlan *m = ASSERT_PTR(netdev)->kind == NETDEV_KIND_MACVLAN ? MACVLAN(netdev) : MACVTAP(netdev);
assert(n);
if (n->kind == NETDEV_KIND_MACVLAN)
m = MACVLAN(n);
else
m = MACVTAP(n);
assert(m);
m->mode = _NETDEV_MACVLAN_MODE_INVALID; m->mode = _NETDEV_MACVLAN_MODE_INVALID;
m->bc_queue_length = UINT32_MAX; m->bc_queue_length = UINT32_MAX;

View file

@ -6,11 +6,11 @@
#include "string-table.h" #include "string-table.h"
static const char * const netdev_local_address_type_table[_NETDEV_LOCAL_ADDRESS_TYPE_MAX] = { static const char * const netdev_local_address_type_table[_NETDEV_LOCAL_ADDRESS_TYPE_MAX] = {
[NETDEV_LOCAL_ADDRESS_IPV4LL] = "ipv4_link_local", [NETDEV_LOCAL_ADDRESS_IPV4LL] = "ipv4_link_local",
[NETDEV_LOCAL_ADDRESS_IPV6LL] = "ipv6_link_local", [NETDEV_LOCAL_ADDRESS_IPV6LL] = "ipv6_link_local",
[NETDEV_LOCAL_ADDRESS_DHCP4] = "dhcp4", [NETDEV_LOCAL_ADDRESS_DHCP4] = "dhcp4",
[NETDEV_LOCAL_ADDRESS_DHCP6] = "dhcp6", [NETDEV_LOCAL_ADDRESS_DHCP6] = "dhcp6",
[NETDEV_LOCAL_ADDRESS_SLAAC] = "slaac", [NETDEV_LOCAL_ADDRESS_SLAAC] = "slaac",
}; };
DEFINE_STRING_TABLE_LOOKUP(netdev_local_address_type, NetDevLocalAddressType); DEFINE_STRING_TABLE_LOOKUP(netdev_local_address_type, NetDevLocalAddressType);

View file

@ -182,14 +182,13 @@ extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX];
#define NETDEV_VTABLE(n) ((n)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(n)->kind] : NULL) #define NETDEV_VTABLE(n) ((n)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(n)->kind] : NULL)
/* For casting a netdev into the various netdev kinds */ /* For casting a netdev into the various netdev kinds */
#define DEFINE_NETDEV_CAST(UPPERCASE, MixedCase) \ #define DEFINE_NETDEV_CAST(UPPERCASE, MixedCase) \
static inline MixedCase* UPPERCASE(NetDev *n) { \ static inline MixedCase* UPPERCASE(NetDev *n) { \
if (_unlikely_(!n || \ assert(n); \
n->kind != NETDEV_KIND_##UPPERCASE) || \ assert(n->kind == NETDEV_KIND_##UPPERCASE); \
n->state == _NETDEV_STATE_INVALID) \ assert(n->state < _NETDEV_STATE_MAX); \
return NULL; \ \
\ return (MixedCase*) n; \
return (MixedCase*) n; \
} }
/* For casting the various netdev kinds into a netdev */ /* For casting the various netdev kinds into a netdev */

View file

@ -25,7 +25,7 @@
static const char* const ip6tnl_mode_table[_NETDEV_IP6_TNL_MODE_MAX] = { static const char* const ip6tnl_mode_table[_NETDEV_IP6_TNL_MODE_MAX] = {
[NETDEV_IP6_TNL_MODE_IP6IP6] = "ip6ip6", [NETDEV_IP6_TNL_MODE_IP6IP6] = "ip6ip6",
[NETDEV_IP6_TNL_MODE_IPIP6] = "ipip6", [NETDEV_IP6_TNL_MODE_IPIP6] = "ipip6",
[NETDEV_IP6_TNL_MODE_ANYIP6] = "any", [NETDEV_IP6_TNL_MODE_ANYIP6] = "any",
}; };
@ -199,19 +199,11 @@ static int tunnel_get_local_address(Tunnel *t, Link *link, union in_addr_union *
} }
static int netdev_ipip_sit_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { static int netdev_ipip_sit_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
union in_addr_union local;
Tunnel *t;
int r;
assert(netdev);
assert(m); assert(m);
if (netdev->kind == NETDEV_KIND_IPIP) union in_addr_union local;
t = IPIP(netdev); Tunnel *t = ASSERT_PTR(netdev)->kind == NETDEV_KIND_IPIP ? IPIP(netdev) : SIT(netdev);
else int r;
t = SIT(netdev);
assert(t);
if (t->external) { if (t->external) {
r = sd_netlink_message_append_flag(m, IFLA_IPTUN_COLLECT_METADATA); r = sd_netlink_message_append_flag(m, IFLA_IPTUN_COLLECT_METADATA);
@ -268,8 +260,8 @@ static int netdev_ipip_sit_fill_message_create(NetDev *netdev, Link *link, sd_ne
if (r < 0) if (r < 0)
return r; return r;
/* u16 is deliberate here, even though we're passing a netmask that can never be >128. The kernel is /* u16 is deliberate here, even though we're passing a netmask that can never be
* expecting to receive the prefixlen as a u16. * >128. The kernel is expecting to receive the prefixlen as a u16.
*/ */
r = sd_netlink_message_append_u16(m, IFLA_IPTUN_6RD_PREFIXLEN, t->sixrd_prefixlen); r = sd_netlink_message_append_u16(m, IFLA_IPTUN_6RD_PREFIXLEN, t->sixrd_prefixlen);
if (r < 0) if (r < 0)
@ -316,8 +308,6 @@ static int netdev_gre_erspan_fill_message_create(NetDev *netdev, Link *link, sd_
assert_not_reached(); assert_not_reached();
} }
assert(t);
if (t->external) { if (t->external) {
r = sd_netlink_message_append_flag(m, IFLA_GRE_COLLECT_METADATA); r = sd_netlink_message_append_flag(m, IFLA_GRE_COLLECT_METADATA);
if (r < 0) if (r < 0)
@ -441,10 +431,8 @@ static int netdev_gre_erspan_fill_message_create(NetDev *netdev, Link *link, sd_
static int netdev_ip6gre_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { static int netdev_ip6gre_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
union in_addr_union local; union in_addr_union local;
uint32_t ikey = 0; uint32_t ikey = 0, okey = 0;
uint32_t okey = 0; uint16_t iflags = 0, oflags = 0;
uint16_t iflags = 0;
uint16_t oflags = 0;
Tunnel *t; Tunnel *t;
int r; int r;
@ -456,8 +444,6 @@ static int netdev_ip6gre_fill_message_create(NetDev *netdev, Link *link, sd_netl
else else
t = IP6GRETAP(netdev); t = IP6GRETAP(netdev);
assert(t);
if (t->external) { if (t->external) {
r = sd_netlink_message_append_flag(m, IFLA_GRE_COLLECT_METADATA); r = sd_netlink_message_append_flag(m, IFLA_GRE_COLLECT_METADATA);
if (r < 0) if (r < 0)
@ -535,20 +521,13 @@ static int netdev_ip6gre_fill_message_create(NetDev *netdev, Link *link, sd_netl
} }
static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
union in_addr_union local;
uint32_t ikey, okey;
Tunnel *t;
int r;
assert(netdev); assert(netdev);
assert(m); assert(m);
if (netdev->kind == NETDEV_KIND_VTI) union in_addr_union local;
t = VTI(netdev); uint32_t ikey, okey;
else Tunnel *t = netdev->kind == NETDEV_KIND_VTI ? VTI(netdev) : VTI6(netdev);
t = VTI6(netdev); int r;
assert(t);
if (link || t->assign_to_loopback) { if (link || t->assign_to_loopback) {
r = sd_netlink_message_append_u32(m, IFLA_VTI_LINK, link ? link->ifindex : LOOPBACK_IFINDEX); r = sd_netlink_message_append_u32(m, IFLA_VTI_LINK, link ? link->ifindex : LOOPBACK_IFINDEX);
@ -587,17 +566,13 @@ static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_netlink
} }
static int netdev_ip6tnl_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { static int netdev_ip6tnl_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
union in_addr_union local;
uint8_t proto;
Tunnel *t;
int r;
assert(netdev); assert(netdev);
assert(m); assert(m);
t = IP6TNL(netdev); union in_addr_union local;
uint8_t proto;
assert(t); Tunnel *t = IP6TNL(netdev);
int r;
switch (t->ip6tnl_mode) { switch (t->ip6tnl_mode) {
case NETDEV_IP6_TNL_MODE_IP6IP6: case NETDEV_IP6_TNL_MODE_IP6IP6:
@ -673,13 +648,9 @@ static int netdev_ip6tnl_fill_message_create(NetDev *netdev, Link *link, sd_netl
} }
static int netdev_tunnel_is_ready_to_create(NetDev *netdev, Link *link) { static int netdev_tunnel_is_ready_to_create(NetDev *netdev, Link *link) {
Tunnel *t;
assert(netdev); assert(netdev);
t = TUNNEL(netdev); Tunnel *t = ASSERT_PTR(TUNNEL(netdev));
assert(t);
if (t->independent) if (t->independent)
return true; return true;
@ -688,14 +659,10 @@ static int netdev_tunnel_is_ready_to_create(NetDev *netdev, Link *link) {
} }
static int netdev_tunnel_verify(NetDev *netdev, const char *filename) { static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
Tunnel *t;
assert(netdev); assert(netdev);
assert(filename); assert(filename);
t = TUNNEL(netdev); Tunnel *t = ASSERT_PTR(TUNNEL(netdev));
assert(t);
if (netdev->kind == NETDEV_KIND_IP6TNL && if (netdev->kind == NETDEV_KIND_IP6TNL &&
t->ip6tnl_mode == _NETDEV_IP6_TNL_MODE_INVALID) t->ip6tnl_mode == _NETDEV_IP6_TNL_MODE_INVALID)
@ -931,7 +898,8 @@ int config_parse_ipv6_flowlabel(
void *userdata) { void *userdata) {
Tunnel *t = ASSERT_PTR(userdata); Tunnel *t = ASSERT_PTR(userdata);
int k, r; uint32_t k;
int r;
assert(filename); assert(filename);
assert(rvalue); assert(rvalue);
@ -942,21 +910,15 @@ int config_parse_ipv6_flowlabel(
return 0; return 0;
} }
r = safe_atoi(rvalue, &k); r = config_parse_uint32_bounded(
if (r < 0) { unit, filename, line, section, section_line, lvalue, rvalue,
log_syntax(unit, LOG_WARNING, filename, line, r, 0, 0xFFFFF, true,
"Failed to parse tunnel IPv6 flowlabel, ignoring assignment: %s", rvalue); &k);
return 0; if (r <= 0)
} return r;
if (k > 0xFFFFF) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Invalid tunnel IPv6 flowlabel, ignoring assignment: %s", rvalue);
return 0;
}
t->ipv6_flowlabel = htobe32(k) & IP6_FLOWINFO_FLOWLABEL; t->ipv6_flowlabel = htobe32(k) & IP6_FLOWINFO_FLOWLABEL;
t->flags &= ~IP6_TNL_F_USE_ORIG_FLOWLABEL; t->flags &= ~IP6_TNL_F_USE_ORIG_FLOWLABEL;
return 0; return 0;
} }
@ -972,33 +934,26 @@ int config_parse_encap_limit(
void *data, void *data,
void *userdata) { void *userdata) {
Tunnel *t = ASSERT_PTR(userdata);
int k, r;
assert(filename); assert(filename);
assert(rvalue); assert(rvalue);
Tunnel *t = ASSERT_PTR(userdata);
int r;
if (streq(rvalue, "none")) { if (streq(rvalue, "none")) {
t->flags |= IP6_TNL_F_IGN_ENCAP_LIMIT;
t->encap_limit = 0; t->encap_limit = 0;
t->flags |= IP6_TNL_F_IGN_ENCAP_LIMIT;
return 0; return 0;
} }
r = safe_atoi(rvalue, &k); r = config_parse_uint8_bounded(
if (r < 0) { unit, filename, line, section, section_line, lvalue, rvalue,
log_syntax(unit, LOG_WARNING, filename, line, r, 0, UINT8_MAX, true,
"Failed to parse Tunnel Encapsulation Limit option, ignoring assignment: %s", rvalue); &t->encap_limit);
return 0; if (r <= 0)
} return r;
if (k > 255 || k < 0) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Invalid Tunnel Encapsulation value, ignoring assignment: %d", k);
return 0;
}
t->encap_limit = k;
t->flags &= ~IP6_TNL_F_IGN_ENCAP_LIMIT; t->flags &= ~IP6_TNL_F_IGN_ENCAP_LIMIT;
return 0; return 0;
} }
@ -1051,32 +1006,21 @@ int config_parse_erspan_version(
void *data, void *data,
void *userdata) { void *userdata) {
uint8_t n, *v = ASSERT_PTR(data);
int r;
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
uint8_t *v = ASSERT_PTR(data);
if (isempty(rvalue)) { if (isempty(rvalue)) {
*v = 1; /* defaults to 1 */ *v = 1; /* defaults to 1 */
return 0; return 0;
} }
r = safe_atou8(rvalue, &n); return config_parse_uint8_bounded(
if (r < 0) { unit, filename, line, section, section_line, lvalue, rvalue,
log_syntax(unit, LOG_WARNING, filename, line, r, 0, 2, true,
"Failed to parse erspan version \"%s\", ignoring: %m", rvalue); v);
return 0;
}
if (!IN_SET(n, 0, 1, 2)) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Invalid erspan version \"%s\", which must be 0, 1 or 2, ignoring.", rvalue);
return 0;
}
*v = n;
return 0;
} }
int config_parse_erspan_index( int config_parse_erspan_index(
@ -1091,32 +1035,21 @@ int config_parse_erspan_index(
void *data, void *data,
void *userdata) { void *userdata) {
uint32_t n, *v = ASSERT_PTR(data);
int r;
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
uint32_t *v = ASSERT_PTR(data);
if (isempty(rvalue)) { if (isempty(rvalue)) {
*v = 0; /* defaults to 0 */ *v = 0; /* defaults to 0 */
return 0; return 0;
} }
r = safe_atou32(rvalue, &n); return config_parse_uint32_bounded(
if (r < 0) { unit, filename, line, section, section_line, lvalue, rvalue,
log_syntax(unit, LOG_WARNING, filename, line, r, 0, 0x100000 - 1, true,
"Failed to parse erspan index \"%s\", ignoring: %m", rvalue); v);
return 0;
}
if (n >= 0x100000) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Invalid erspan index \"%s\", which must be less than 0x100000, ignoring.", rvalue);
return 0;
}
*v = n;
return 0;
} }
int config_parse_erspan_direction( int config_parse_erspan_direction(
@ -1131,12 +1064,12 @@ int config_parse_erspan_direction(
void *data, void *data,
void *userdata) { void *userdata) {
uint8_t *v = ASSERT_PTR(data);
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
uint8_t *v = ASSERT_PTR(data);
if (isempty(rvalue) || streq(rvalue, "ingress")) if (isempty(rvalue) || streq(rvalue, "ingress"))
*v = 0; /* defaults to ingress */ *v = 0; /* defaults to ingress */
else if (streq(rvalue, "egress")) else if (streq(rvalue, "egress"))
@ -1160,42 +1093,25 @@ int config_parse_erspan_hwid(
void *data, void *data,
void *userdata) { void *userdata) {
uint16_t n, *v = ASSERT_PTR(data);
int r;
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
uint16_t *v = ASSERT_PTR(data);
if (isempty(rvalue)) { if (isempty(rvalue)) {
*v = 0; /* defaults to 0 */ *v = 0; /* defaults to 0 */
return 0; return 0;
} }
r = safe_atou16(rvalue, &n); return config_parse_uint16_bounded(
if (r < 0) { unit, filename, line, section, section_line, lvalue, rvalue,
log_syntax(unit, LOG_WARNING, filename, line, r, 0, 63, true,
"Failed to parse erspan hwid \"%s\", ignoring: %m", rvalue); v);
return 0;
}
if (n >= 64) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Invalid erspan index \"%s\", which must be less than 64, ignoring.", rvalue);
return 0;
}
*v = n;
return 0;
} }
static void netdev_tunnel_init(NetDev *netdev) { static void netdev_tunnel_init(NetDev *netdev) {
Tunnel *t; Tunnel *t = ASSERT_PTR(TUNNEL(netdev));
assert(netdev);
t = TUNNEL(netdev);
assert(t);
t->local_type = _NETDEV_LOCAL_ADDRESS_TYPE_INVALID; t->local_type = _NETDEV_LOCAL_ADDRESS_TYPE_INVALID;
t->pmtudisc = -1; t->pmtudisc = -1;

View file

@ -10,17 +10,12 @@
#include "veth.h" #include "veth.h"
static int netdev_veth_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { static int netdev_veth_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
struct hw_addr_data hw_addr;
Veth *v;
int r;
assert(netdev);
assert(!link); assert(!link);
assert(m); assert(m);
v = VETH(netdev); struct hw_addr_data hw_addr;
Veth *v = VETH(netdev);
assert(v); int r;
r = sd_netlink_message_open_container(m, VETH_INFO_PEER); r = sd_netlink_message_open_container(m, VETH_INFO_PEER);
if (r < 0) if (r < 0)
@ -57,14 +52,9 @@ static int netdev_veth_fill_message_create(NetDev *netdev, Link *link, sd_netlin
} }
static int netdev_veth_verify(NetDev *netdev, const char *filename) { static int netdev_veth_verify(NetDev *netdev, const char *filename) {
Veth *v;
assert(netdev);
assert(filename); assert(filename);
v = VETH(netdev); Veth *v = VETH(netdev);
assert(v);
if (!v->ifname_peer) if (!v->ifname_peer)
return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL), return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
@ -74,14 +64,8 @@ static int netdev_veth_verify(NetDev *netdev, const char *filename) {
return 0; return 0;
} }
static void veth_done(NetDev *n) { static void veth_done(NetDev *netdev) {
Veth *v; Veth *v = VETH(netdev);
assert(n);
v = VETH(n);
assert(v);
free(v->ifname_peer); free(v->ifname_peer);
} }

View file

@ -10,17 +10,12 @@
#include "vlan.h" #include "vlan.h"
static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *req) { static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *req) {
struct ifla_vlan_flags flags = {};
VLan *v;
int r;
assert(netdev);
assert(link); assert(link);
assert(req); assert(req);
v = VLAN(netdev); struct ifla_vlan_flags flags = {};
VLan *v = VLAN(netdev);
assert(v); int r;
r = sd_netlink_message_append_u16(req, IFLA_VLAN_ID, v->id); r = sd_netlink_message_append_u16(req, IFLA_VLAN_ID, v->id);
if (r < 0) if (r < 0)
@ -180,14 +175,9 @@ int config_parse_vlan_qos_maps(
} }
static int netdev_vlan_verify(NetDev *netdev, const char *filename) { static int netdev_vlan_verify(NetDev *netdev, const char *filename) {
VLan *v;
assert(netdev);
assert(filename); assert(filename);
v = VLAN(netdev); VLan *v = VLAN(netdev);
assert(v);
if (v->id == VLANID_INVALID) { if (v->id == VLANID_INVALID) {
log_netdev_warning(netdev, "VLAN without valid Id (%"PRIu16") configured in %s.", v->id, filename); log_netdev_warning(netdev, "VLAN without valid Id (%"PRIu16") configured in %s.", v->id, filename);
@ -197,12 +187,8 @@ static int netdev_vlan_verify(NetDev *netdev, const char *filename) {
return 0; return 0;
} }
static void vlan_done(NetDev *n) { static void vlan_done(NetDev *netdev) {
VLan *v; VLan *v = VLAN(netdev);
v = VLAN(n);
assert(v);
set_free(v->egress_qos_maps); set_free(v->egress_qos_maps);
set_free(v->ingress_qos_maps); set_free(v->ingress_qos_maps);
@ -211,9 +197,6 @@ static void vlan_done(NetDev *n) {
static void vlan_init(NetDev *netdev) { static void vlan_init(NetDev *netdev) {
VLan *v = VLAN(netdev); VLan *v = VLAN(netdev);
assert(netdev);
assert(v);
v->id = VLANID_INVALID; v->id = VLANID_INVALID;
v->protocol = -1; v->protocol = -1;
v->gvrp = -1; v->gvrp = -1;

View file

@ -7,16 +7,11 @@
#include "vrf.h" #include "vrf.h"
static int netdev_vrf_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { static int netdev_vrf_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
Vrf *v;
int r;
assert(netdev);
assert(!link); assert(!link);
assert(m); assert(m);
v = VRF(netdev); Vrf *v = VRF(netdev);
int r;
assert(v);
r = sd_netlink_message_append_u32(m, IFLA_VRF_TABLE, v->table); r = sd_netlink_message_append_u32(m, IFLA_VRF_TABLE, v->table);
if (r < 0) if (r < 0)

View file

@ -6,16 +6,11 @@
#include "vxcan.h" #include "vxcan.h"
static int netdev_vxcan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { static int netdev_vxcan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
VxCan *v;
int r;
assert(netdev);
assert(!link); assert(!link);
assert(m); assert(m);
v = VXCAN(netdev); VxCan *v = VXCAN(netdev);
int r;
assert(v);
r = sd_netlink_message_open_container(m, VXCAN_INFO_PEER); r = sd_netlink_message_open_container(m, VXCAN_INFO_PEER);
if (r < 0) if (r < 0)
@ -35,14 +30,9 @@ static int netdev_vxcan_fill_message_create(NetDev *netdev, Link *link, sd_netli
} }
static int netdev_vxcan_verify(NetDev *netdev, const char *filename) { static int netdev_vxcan_verify(NetDev *netdev, const char *filename) {
VxCan *v;
assert(netdev);
assert(filename); assert(filename);
v = VXCAN(netdev); VxCan *v = VXCAN(netdev);
assert(v);
if (!v->ifname_peer) if (!v->ifname_peer)
return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL), return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
@ -51,14 +41,8 @@ static int netdev_vxcan_verify(NetDev *netdev, const char *filename) {
return 0; return 0;
} }
static void vxcan_done(NetDev *n) { static void vxcan_done(NetDev *netdev) {
VxCan *v; VxCan *v = VXCAN(netdev);
assert(n);
v = VXCAN(n);
assert(v);
free(v->ifname_peer); free(v->ifname_peer);
} }

View file

@ -14,8 +14,8 @@
#include "vxlan.h" #include "vxlan.h"
static const char* const df_table[_NETDEV_VXLAN_DF_MAX] = { static const char* const df_table[_NETDEV_VXLAN_DF_MAX] = {
[NETDEV_VXLAN_DF_NO] = "no", [NETDEV_VXLAN_DF_NO] = "no",
[NETDEV_VXLAN_DF_YES] = "yes", [NETDEV_VXLAN_DF_YES] = "yes",
[NETDEV_VXLAN_DF_INHERIT] = "inherit", [NETDEV_VXLAN_DF_INHERIT] = "inherit",
}; };
@ -37,16 +37,11 @@ static int vxlan_get_local_address(VxLan *v, Link *link, int *ret_family, union
} }
static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
union in_addr_union local;
int local_family, r;
VxLan *v;
assert(netdev);
assert(m); assert(m);
v = VXLAN(netdev); union in_addr_union local;
int local_family, r;
assert(v); VxLan *v = VXLAN(netdev);
if (v->vni <= VXLAN_VID_MAX) { if (v->vni <= VXLAN_VID_MAX) {
r = sd_netlink_message_append_u32(m, IFLA_VXLAN_ID, v->vni); r = sd_netlink_message_append_u32(m, IFLA_VXLAN_ID, v->vni);
@ -286,25 +281,18 @@ int config_parse_port_range(
void *data, void *data,
void *userdata) { void *userdata) {
VxLan *v = userdata;
uint16_t low, high;
int r;
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
assert(data); assert(data);
r = parse_ip_port_range(rvalue, &low, &high); VxLan *v = ASSERT_PTR(userdata);
if (r < 0) { int r;
r = parse_ip_port_range(rvalue, &v->port_range.low, &v->port_range.high);
if (r < 0)
log_syntax(unit, LOG_WARNING, filename, line, r, log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse VXLAN port range '%s'. Port should be greater than 0 and less than 65535.", rvalue); "Failed to parse VXLAN port range '%s'. Port should be greater than 0 and less than 65535.", rvalue);
return 0;
}
v->port_range.low = low;
v->port_range.high = high;
return 0; return 0;
} }
@ -358,44 +346,35 @@ int config_parse_vxlan_ttl(
void *data, void *data,
void *userdata) { void *userdata) {
VxLan *v = userdata;
unsigned f;
int r;
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
assert(data); assert(data);
if (streq(rvalue, "inherit")) VxLan *v = ASSERT_PTR(userdata);
int r;
if (streq(rvalue, "inherit")) {
v->inherit = true; v->inherit = true;
else { v->ttl = 0; /* unset the unused ttl field for clarity */
r = safe_atou(rvalue, &f); return 0;
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse VXLAN TTL '%s', ignoring assignment: %m", rvalue);
return 0;
}
if (f > 255) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Invalid VXLAN TTL '%s'. TTL must be <= 255. Ignoring assignment.", rvalue);
return 0;
}
v->ttl = f;
} }
r = config_parse_unsigned_bounded(
unit, filename, line, section, section_line, lvalue, rvalue,
0, UINT8_MAX, true,
&v->ttl);
if (r <= 0)
return r;
v->inherit = false;
return 0; return 0;
} }
static int netdev_vxlan_verify(NetDev *netdev, const char *filename) { static int netdev_vxlan_verify(NetDev *netdev, const char *filename) {
VxLan *v = VXLAN(netdev);
assert(netdev);
assert(v);
assert(filename); assert(filename);
VxLan *v = VXLAN(netdev);
if (v->vni > VXLAN_VID_MAX) if (v->vni > VXLAN_VID_MAX)
return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL), return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
"%s: VXLAN without valid VNI (or VXLAN Segment ID) configured. Ignoring.", "%s: VXLAN without valid VNI (or VXLAN Segment ID) configured. Ignoring.",
@ -423,13 +402,7 @@ static int netdev_vxlan_verify(NetDev *netdev, const char *filename) {
} }
static int netdev_vxlan_is_ready_to_create(NetDev *netdev, Link *link) { static int netdev_vxlan_is_ready_to_create(NetDev *netdev, Link *link) {
VxLan *v; VxLan *v = VXLAN(netdev);
assert(netdev);
v = VXLAN(netdev);
assert(v);
if (v->independent) if (v->independent)
return true; return true;
@ -438,13 +411,7 @@ static int netdev_vxlan_is_ready_to_create(NetDev *netdev, Link *link) {
} }
static void vxlan_init(NetDev *netdev) { static void vxlan_init(NetDev *netdev) {
VxLan *v; VxLan *v = VXLAN(netdev);
assert(netdev);
v = VXLAN(netdev);
assert(v);
v->local_type = _NETDEV_LOCAL_ADDRESS_TYPE_INVALID; v->local_type = _NETDEV_LOCAL_ADDRESS_TYPE_INVALID;
v->vni = VXLAN_VID_MAX + 1; v->vni = VXLAN_VID_MAX + 1;

View file

@ -225,17 +225,12 @@ cancel:
static int wireguard_set_interface(NetDev *netdev) { static int wireguard_set_interface(NetDev *netdev) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
WireguardIPmask *mask_start = NULL; WireguardIPmask *mask_start = NULL;
WireguardPeer *peer_start;
bool sent_once = false; bool sent_once = false;
uint32_t serial; uint32_t serial;
Wireguard *w; Wireguard *w = WIREGUARD(netdev);
int r; int r;
assert(netdev); for (WireguardPeer *peer_start = w->peers; peer_start || !sent_once; ) {
w = WIREGUARD(netdev);
assert(w);
for (peer_start = w->peers; peer_start || !sent_once; ) {
uint16_t i = 0; uint16_t i = 0;
message = sd_netlink_message_unref(message); message = sd_netlink_message_unref(message);
@ -428,11 +423,7 @@ static int peer_resolve_endpoint(WireguardPeer *peer) {
} }
static void wireguard_resolve_endpoints(NetDev *netdev) { static void wireguard_resolve_endpoints(NetDev *netdev) {
Wireguard *w; Wireguard *w = WIREGUARD(netdev);
assert(netdev);
w = WIREGUARD(netdev);
assert(w);
LIST_FOREACH(peers, peer, w->peers) LIST_FOREACH(peers, peer, w->peers)
if (peer_resolve_endpoint(peer) == -ENOBUFS) if (peer_resolve_endpoint(peer) == -ENOBUFS)
@ -441,7 +432,6 @@ static void wireguard_resolve_endpoints(NetDev *netdev) {
} }
static int netdev_wireguard_post_create(NetDev *netdev, Link *link) { static int netdev_wireguard_post_create(NetDev *netdev, Link *link) {
assert(netdev);
assert(WIREGUARD(netdev)); assert(WIREGUARD(netdev));
(void) wireguard_set_interface(netdev); (void) wireguard_set_interface(netdev);
@ -537,11 +527,7 @@ int config_parse_wireguard_private_key(
void *data, void *data,
void *userdata) { void *userdata) {
Wireguard *w; Wireguard *w = WIREGUARD(data);
assert(data);
w = WIREGUARD(data);
assert(w);
return wireguard_decode_key_and_warn(rvalue, w->private_key, unit, filename, line, lvalue); return wireguard_decode_key_and_warn(rvalue, w->private_key, unit, filename, line, lvalue);
} }
@ -558,12 +544,8 @@ int config_parse_wireguard_private_key_file(
void *data, void *data,
void *userdata) { void *userdata) {
Wireguard *w = WIREGUARD(data);
_cleanup_free_ char *path = NULL; _cleanup_free_ char *path = NULL;
Wireguard *w;
assert(data);
w = WIREGUARD(data);
assert(w);
if (isempty(rvalue)) { if (isempty(rvalue)) {
w->private_key_file = mfree(w->private_key_file); w->private_key_file = mfree(w->private_key_file);
@ -592,14 +574,10 @@ int config_parse_wireguard_peer_key(
void *data, void *data,
void *userdata) { void *userdata) {
Wireguard *w = WIREGUARD(data);
_cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL; _cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL;
Wireguard *w;
int r; int r;
assert(data);
w = WIREGUARD(data);
assert(w);
r = wireguard_peer_new_static(w, filename, section_line, &peer); r = wireguard_peer_new_static(w, filename, section_line, &peer);
if (r < 0) if (r < 0)
return log_oom(); return log_oom();
@ -626,15 +604,11 @@ int config_parse_wireguard_preshared_key_file(
void *data, void *data,
void *userdata) { void *userdata) {
Wireguard *w = WIREGUARD(data);
_cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL; _cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL;
_cleanup_free_ char *path = NULL; _cleanup_free_ char *path = NULL;
Wireguard *w;
int r; int r;
assert(data);
w = WIREGUARD(data);
assert(w);
r = wireguard_peer_new_static(w, filename, section_line, &peer); r = wireguard_peer_new_static(w, filename, section_line, &peer);
if (r < 0) if (r < 0)
return log_oom(); return log_oom();
@ -669,19 +643,15 @@ int config_parse_wireguard_allowed_ips(
void *data, void *data,
void *userdata) { void *userdata) {
assert(rvalue);
Wireguard *w = WIREGUARD(data);
_cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL; _cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL;
union in_addr_union addr; union in_addr_union addr;
unsigned char prefixlen; unsigned char prefixlen;
int r, family; int r, family;
Wireguard *w;
WireguardIPmask *ipmask; WireguardIPmask *ipmask;
assert(rvalue);
assert(data);
w = WIREGUARD(data);
assert(w);
r = wireguard_peer_new_static(w, filename, section_line, &peer); r = wireguard_peer_new_static(w, filename, section_line, &peer);
if (r < 0) if (r < 0)
return log_oom(); return log_oom();
@ -751,21 +721,18 @@ int config_parse_wireguard_endpoint(
void *data, void *data,
void *userdata) { void *userdata) {
assert(filename);
assert(rvalue);
assert(userdata);
Wireguard *w = WIREGUARD(userdata);
_cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL; _cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL;
_cleanup_free_ char *host = NULL; _cleanup_free_ char *host = NULL;
union in_addr_union addr; union in_addr_union addr;
const char *p; const char *p;
uint16_t port; uint16_t port;
Wireguard *w;
int family, r; int family, r;
assert(filename);
assert(rvalue);
assert(userdata);
w = WIREGUARD(userdata);
assert(w);
r = wireguard_peer_new_static(w, filename, section_line, &peer); r = wireguard_peer_new_static(w, filename, section_line, &peer);
if (r < 0) if (r < 0)
return log_oom(); return log_oom();
@ -846,17 +813,13 @@ int config_parse_wireguard_keepalive(
void *data, void *data,
void *userdata) { void *userdata) {
assert(rvalue);
Wireguard *w = WIREGUARD(data);
_cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL; _cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL;
uint16_t keepalive = 0; uint16_t keepalive = 0;
Wireguard *w;
int r; int r;
assert(rvalue);
assert(data);
w = WIREGUARD(data);
assert(w);
r = wireguard_peer_new_static(w, filename, section_line, &peer); r = wireguard_peer_new_static(w, filename, section_line, &peer);
if (r < 0) if (r < 0)
return log_oom(); return log_oom();
@ -927,18 +890,14 @@ int config_parse_wireguard_peer_route_table(
void *data, void *data,
void *userdata) { void *userdata) {
Wireguard *w = WIREGUARD(userdata);
_cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL; _cleanup_(wireguard_peer_free_or_set_invalidp) WireguardPeer *peer = NULL;
NetDev *netdev = ASSERT_PTR(userdata);
Wireguard *w;
int r; int r;
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
assert(netdev->manager); assert(NETDEV(w)->manager);
w = WIREGUARD(netdev);
assert(w);
r = wireguard_peer_new_static(w, filename, section_line, &peer); r = wireguard_peer_new_static(w, filename, section_line, &peer);
if (r < 0) if (r < 0)
@ -957,7 +916,7 @@ int config_parse_wireguard_peer_route_table(
return 0; return 0;
} }
r = manager_get_route_table_from_string(netdev->manager, rvalue, &peer->route_table); r = manager_get_route_table_from_string(NETDEV(w)->manager, rvalue, &peer->route_table);
if (r < 0) { if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse %s=, ignoring assignment: %s", "Failed to parse %s=, ignoring assignment: %s",
@ -1051,21 +1010,13 @@ int config_parse_wireguard_peer_route_priority(
} }
static void wireguard_init(NetDev *netdev) { static void wireguard_init(NetDev *netdev) {
Wireguard *w; Wireguard *w = WIREGUARD(netdev);
assert(netdev);
w = WIREGUARD(netdev);
assert(w);
w->flags = WGDEVICE_F_REPLACE_PEERS; w->flags = WGDEVICE_F_REPLACE_PEERS;
} }
static void wireguard_done(NetDev *netdev) { static void wireguard_done(NetDev *netdev) {
Wireguard *w; Wireguard *w = WIREGUARD(netdev);
assert(netdev);
w = WIREGUARD(netdev);
assert(w);
explicit_bzero_safe(w->private_key, WG_KEY_LEN); explicit_bzero_safe(w->private_key, WG_KEY_LEN);
free(w->private_key_file); free(w->private_key_file);
@ -1124,13 +1075,9 @@ static int wireguard_peer_verify(WireguardPeer *peer) {
} }
static int wireguard_verify(NetDev *netdev, const char *filename) { static int wireguard_verify(NetDev *netdev, const char *filename) {
Wireguard *w; Wireguard *w = WIREGUARD(netdev);
int r; int r;
assert(netdev);
w = WIREGUARD(netdev);
assert(w);
r = wireguard_read_key_file(w->private_key_file, w->private_key); r = wireguard_read_key_file(w->private_key_file, w->private_key);
if (r < 0) if (r < 0)
return log_netdev_error_errno(netdev, r, return log_netdev_error_errno(netdev, r,

View file

@ -12,38 +12,20 @@
#include "wlan.h" #include "wlan.h"
static void wlan_done(NetDev *netdev) { static void wlan_done(NetDev *netdev) {
WLan *w; WLan *w = WLAN(netdev);
assert(netdev);
w = WLAN(netdev);
assert(w);
w->wiphy_name = mfree(w->wiphy_name); w->wiphy_name = mfree(w->wiphy_name);
} }
static void wlan_init(NetDev *netdev) { static void wlan_init(NetDev *netdev) {
WLan *w; WLan *w = WLAN(netdev);
assert(netdev);
w = WLAN(netdev);
assert(w);
w->wiphy_index = UINT32_MAX; w->wiphy_index = UINT32_MAX;
w->wds = -1; w->wds = -1;
} }
static int wlan_get_wiphy(NetDev *netdev, Wiphy **ret) { static int wlan_get_wiphy(NetDev *netdev, Wiphy **ret) {
WLan *w; WLan *w = WLAN(netdev);
assert(netdev);
w = WLAN(netdev);
assert(w);
if (w->wiphy_name) if (w->wiphy_name)
return wiphy_get_by_name(netdev->manager, w->wiphy_name, ret); return wiphy_get_by_name(netdev->manager, w->wiphy_name, ret);
@ -56,17 +38,10 @@ static int wlan_is_ready_to_create(NetDev *netdev, Link *link) {
} }
static int wlan_fill_message(NetDev *netdev, sd_netlink_message *m) { static int wlan_fill_message(NetDev *netdev, sd_netlink_message *m) {
WLan *w = WLAN(netdev);
Wiphy *wiphy; Wiphy *wiphy;
WLan *w;
int r; int r;
assert(netdev);
assert(m);
w = WLAN(netdev);
assert(w);
r = wlan_get_wiphy(netdev, &wiphy); r = wlan_get_wiphy(netdev, &wiphy);
if (r < 0) if (r < 0)
return r; return r;
@ -145,15 +120,10 @@ static int wlan_create(NetDev *netdev) {
} }
static int wlan_verify(NetDev *netdev, const char *filename) { static int wlan_verify(NetDev *netdev, const char *filename) {
WLan *w; WLan *w = WLAN(netdev);
assert(netdev);
assert(filename); assert(filename);
w = WLAN(netdev);
assert(w);
if (w->iftype == NL80211_IFTYPE_UNSPECIFIED) if (w->iftype == NL80211_IFTYPE_UNSPECIFIED)
return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL), return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
"%s: WLAN interface type is not specified, ignoring.", "%s: WLAN interface type is not specified, ignoring.",
@ -179,7 +149,7 @@ int config_parse_wiphy(
void *data, void *data,
void *userdata) { void *userdata) {
WLan *w = ASSERT_PTR(userdata); WLan *w = WLAN(userdata);
int r; int r;
assert(filename); assert(filename);

View file

@ -6,15 +6,11 @@
#include "xfrm.h" #include "xfrm.h"
static int xfrm_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *message) { static int xfrm_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *message) {
Xfrm *x;
int r;
assert(netdev);
assert(message); assert(message);
x = XFRM(netdev); Xfrm *x = XFRM(netdev);
int r;
assert(x);
assert(link || x->independent); assert(link || x->independent);
r = sd_netlink_message_append_u32(message, IFLA_XFRM_LINK, link ? link->ifindex : LOOPBACK_IFINDEX); r = sd_netlink_message_append_u32(message, IFLA_XFRM_LINK, link ? link->ifindex : LOOPBACK_IFINDEX);
@ -29,19 +25,13 @@ static int xfrm_fill_message_create(NetDev *netdev, Link *link, sd_netlink_messa
} }
static int xfrm_verify(NetDev *netdev, const char *filename) { static int xfrm_verify(NetDev *netdev, const char *filename) {
Xfrm *x;
assert(netdev);
assert(filename); assert(filename);
x = XFRM(netdev); Xfrm *x = XFRM(netdev);
assert(x);
if (x->if_id == 0) if (x->if_id == 0)
return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL), return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
"%s: Xfrm interface ID cannot be zero.", filename); "%s: Xfrm interface ID cannot be zero.", filename);
return 0; return 0;
} }

View file

@ -209,8 +209,6 @@ int network_verify(Network *network) {
else else
continue; continue;
assert(m);
if (m->mode == NETDEV_MACVLAN_MODE_PASSTHRU) if (m->mode == NETDEV_MACVLAN_MODE_PASSTHRU)
network->link_local = ADDRESS_FAMILY_NO; network->link_local = ADDRESS_FAMILY_NO;

View file

@ -889,15 +889,14 @@ static bool route_by_kernel(const Route *route) {
} }
static void link_unmark_wireguard_routes(Link *link) { static void link_unmark_wireguard_routes(Link *link) {
Route *route, *existing;
Wireguard *w;
assert(link); assert(link);
w = WIREGUARD(link->netdev); if (!link->netdev || link->netdev->kind != NETDEV_KIND_WIREGUARD)
if (!w)
return; return;
Route *route, *existing;
Wireguard *w = WIREGUARD(link->netdev);
SET_FOREACH(route, w->routes) SET_FOREACH(route, w->routes)
if (route_get(NULL, link, route, &existing) >= 0) if (route_get(NULL, link, route, &existing) >= 0)
route_unmark(existing); route_unmark(existing);
@ -1527,7 +1526,6 @@ static int link_request_static_route(Link *link, Route *route) {
static int link_request_wireguard_routes(Link *link, bool only_ipv4) { static int link_request_wireguard_routes(Link *link, bool only_ipv4) {
NetDev *netdev; NetDev *netdev;
Wireguard *w;
Route *route; Route *route;
int r; int r;
@ -1539,9 +1537,7 @@ static int link_request_wireguard_routes(Link *link, bool only_ipv4) {
if (netdev_get(link->manager, link->ifname, &netdev) < 0) if (netdev_get(link->manager, link->ifname, &netdev) < 0)
return 0; return 0;
w = WIREGUARD(netdev); Wireguard *w = WIREGUARD(netdev);
if (!w)
return 0;
SET_FOREACH(route, w->routes) { SET_FOREACH(route, w->routes) {
if (only_ipv4 && route->family != AF_INET) if (only_ipv4 && route->family != AF_INET)

View file

@ -87,7 +87,7 @@ static int run(int argc, char *argv[]) {
r = manager_setup(m); r = manager_setup(m);
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not setup manager: %m"); return log_error_errno(r, "Could not set up manager: %m");
r = manager_parse_config_file(m); r = manager_parse_config_file(m);
if (r < 0) if (r < 0)

View file

@ -1908,6 +1908,44 @@ int config_parse_in_addr_non_null(
return 0; return 0;
} }
int config_parse_unsigned_bounded(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *name,
const char *value,
unsigned min,
unsigned max,
bool ignoring,
unsigned *ret) {
int r;
assert(filename);
assert(name);
assert(value);
assert(ret);
r = safe_atou_bounded(value, min, max, ret);
if (r == -ERANGE)
log_syntax(unit, LOG_WARNING, filename, line, r,
"Invalid '%s=%s', allowed range is %u..%u%s.",
name, value, min, max, ignoring ? ", ignoring" : "");
else if (r < 0)
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse '%s=%s'%s: %m",
name, value, ignoring ? ", ignoring" : "");
if (r >= 0)
return 1; /* Return 1 if something was set */
else if (ignoring)
return 0;
else
return r;
}
DEFINE_CONFIG_PARSE(config_parse_percent, parse_percent, "Failed to parse percent value"); DEFINE_CONFIG_PARSE(config_parse_percent, parse_percent, "Failed to parse percent value");
DEFINE_CONFIG_PARSE(config_parse_permyriad, parse_permyriad, "Failed to parse permyriad value"); DEFINE_CONFIG_PARSE(config_parse_permyriad, parse_permyriad, "Failed to parse permyriad value");
DEFINE_CONFIG_PARSE_PTR(config_parse_sec_fix_0, parse_sec_fix_0, usec_t, "Failed to parse time value"); DEFINE_CONFIG_PARSE_PTR(config_parse_sec_fix_0, parse_sec_fix_0, usec_t, "Failed to parse time value");

View file

@ -385,3 +385,97 @@ typedef enum ConfigParseStringFlags {
\ \
return free_and_replace(*enums, xs); \ return free_and_replace(*enums, xs); \
} }
int config_parse_unsigned_bounded(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *name,
const char *value,
unsigned min,
unsigned max,
bool ignoring,
unsigned *ret);
static inline int config_parse_uint32_bounded(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *name,
const char *value,
uint32_t min,
uint32_t max,
bool ignoring,
uint32_t *ret) {
unsigned t;
int r;
r = config_parse_unsigned_bounded(
unit, filename, line, section, section_line, name, value,
min, max, ignoring,
&t);
if (r <= 0)
return r;
assert(t <= UINT32_MAX);
*ret = t;
return 1;
}
static inline int config_parse_uint16_bounded(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *name,
const char *value,
uint16_t min,
uint16_t max,
bool ignoring,
uint16_t *ret) {
unsigned t;
int r;
r = config_parse_unsigned_bounded(
unit, filename, line, section, section_line, name, value,
min, max, ignoring,
&t);
if (r <= 0)
return r;
assert(t <= UINT16_MAX);
*ret = t;
return 1;
}
static inline int config_parse_uint8_bounded(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *name,
const char *value,
uint8_t min,
uint8_t max,
bool ignoring,
uint8_t *ret) {
unsigned t;
int r;
r = config_parse_unsigned_bounded(
unit, filename, line, section, section_line, name, value,
min, max, ignoring,
&t);
if (r <= 0)
return r;
assert(t <= UINT8_MAX);
*ret = t;
return 1;
}

View file

@ -37,33 +37,40 @@ int ip_protocol_from_name(const char *name) {
return sc->id; return sc->id;
} }
int parse_ip_protocol(const char *s) { int parse_ip_protocol_full(const char *s, bool relaxed) {
_cleanup_free_ char *str = NULL; int r, p;
int i, r;
assert(s); assert(s);
if (isempty(s)) if (isempty(s))
return IPPROTO_IP; return IPPROTO_IP;
/* Do not use strdupa() here, as the input string may come from * /* People commonly use lowercase protocol names, which we can look up very quickly, so let's try that
* command line or config files. */ * first. */
str = strdup(s); r = ip_protocol_from_name(s);
if (!str) if (r >= 0)
return -ENOMEM;
i = ip_protocol_from_name(ascii_strlower(str));
if (i >= 0)
return i;
r = safe_atoi(str, &i);
if (r < 0)
return r; return r;
if (!ip_protocol_to_name(i)) /* Do not use strdupa() here, as the input string may come from command line or config files. */
return -EINVAL; _cleanup_free_ char *t = strdup(s);
if (!t)
return -ENOMEM;
return i; r = ip_protocol_from_name(ascii_strlower(t));
if (r >= 0)
return r;
r = safe_atoi(t, &p);
if (r < 0)
return r;
if (p < 0)
return -ERANGE;
/* If @relaxed, we don't check that we have a name for the protocol. */
if (!relaxed && !ip_protocol_to_name(p))
return -EPROTONOSUPPORT;
return p;
} }
const char *ip_protocol_to_tcp_udp(int id) { const char *ip_protocol_to_tcp_udp(int id) {

View file

@ -1,9 +1,14 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once #pragma once
#include <stdbool.h>
const char *ip_protocol_to_name(int id); const char *ip_protocol_to_name(int id);
int ip_protocol_from_name(const char *name); int ip_protocol_from_name(const char *name);
int parse_ip_protocol(const char *s); int parse_ip_protocol_full(const char *s, bool relaxed);
static inline int parse_ip_protocol(const char *s) {
return parse_ip_protocol_full(s, false);
}
const char *ip_protocol_to_tcp_udp(int id); const char *ip_protocol_to_tcp_udp(int id);
int ip_protocol_from_tcp_udp(const char *ip_protocol); int ip_protocol_from_tcp_udp(const char *ip_protocol);

View file

@ -17,13 +17,13 @@ static void test_int(int i) {
assert_se(ip_protocol_from_name(ip_protocol_to_name(parse_ip_protocol(str))) == i); assert_se(ip_protocol_from_name(ip_protocol_to_name(parse_ip_protocol(str))) == i);
} }
static void test_int_fail(int i) { static void test_int_fail(int i, int error) {
char str[DECIMAL_STR_MAX(int)]; char str[DECIMAL_STR_MAX(int)];
assert_se(!ip_protocol_to_name(i)); assert_se(!ip_protocol_to_name(i));
xsprintf(str, "%i", i); xsprintf(str, "%i", i);
assert_se(parse_ip_protocol(str) == -EINVAL); assert_se(parse_ip_protocol(str) == error);
} }
static void test_str(const char *s) { static void test_str(const char *s) {
@ -31,39 +31,41 @@ static void test_str(const char *s) {
assert_se(streq(ip_protocol_to_name(parse_ip_protocol(s)), s)); assert_se(streq(ip_protocol_to_name(parse_ip_protocol(s)), s));
} }
static void test_str_fail(const char *s) { static void test_str_fail(const char *s, int error) {
assert_se(ip_protocol_from_name(s) == -EINVAL); assert_se(ip_protocol_from_name(s) == -EINVAL);
assert_se(parse_ip_protocol(s) == -EINVAL); assert_se(parse_ip_protocol(s) == error);
}
static void test_parse_ip_protocol_one(const char *s, int expected) {
assert_se(parse_ip_protocol(s) == expected);
} }
TEST(integer) { TEST(integer) {
test_int(IPPROTO_TCP); test_int(IPPROTO_TCP);
test_int(IPPROTO_DCCP); test_int(IPPROTO_DCCP);
test_int_fail(-1); test_int_fail(-1, -ERANGE);
test_int_fail(1024 * 1024); test_int_fail(1024 * 1024, -EPROTONOSUPPORT);
} }
TEST(string) { TEST(string) {
test_str("sctp"); test_str("sctp");
test_str("udp"); test_str("udp");
test_str_fail("hoge"); test_str_fail("hoge", -EINVAL);
test_str_fail("-1"); test_str_fail("-1", -ERANGE);
test_str_fail("1000000000"); test_str_fail("1000000000", -EPROTONOSUPPORT);
} }
TEST(parse_ip_protocol) { TEST(parse_ip_protocol) {
test_parse_ip_protocol_one("sctp", IPPROTO_SCTP); assert_se(parse_ip_protocol("sctp") == IPPROTO_SCTP);
test_parse_ip_protocol_one("ScTp", IPPROTO_SCTP); assert_se(parse_ip_protocol("ScTp") == IPPROTO_SCTP);
test_parse_ip_protocol_one("ip", IPPROTO_IP); assert_se(parse_ip_protocol("ip") == IPPROTO_IP);
test_parse_ip_protocol_one("", IPPROTO_IP); assert_se(parse_ip_protocol("") == IPPROTO_IP);
test_parse_ip_protocol_one("1", 1); assert_se(parse_ip_protocol("1") == 1);
test_parse_ip_protocol_one("0", 0); assert_se(parse_ip_protocol("0") == 0);
test_parse_ip_protocol_one("-10", -EINVAL); assert_se(parse_ip_protocol("-10") == -ERANGE);
test_parse_ip_protocol_one("100000000", -EINVAL); assert_se(parse_ip_protocol("100000000") == -EPROTONOSUPPORT);
}
TEST(parse_ip_protocol_full) {
assert_se(parse_ip_protocol_full("-1", true) == -ERANGE);
assert_se(parse_ip_protocol_full("0", true) == 0);
assert_se(parse_ip_protocol_full("11", true) == 11);
} }
DEFINE_TEST_MAIN(LOG_INFO); DEFINE_TEST_MAIN(LOG_INFO);

View file

@ -417,6 +417,32 @@ TEST(parse_range) {
assert_se(upper == 9999); assert_se(upper == 9999);
} }
TEST(safe_atou_bounded) {
int r;
unsigned x;
r = safe_atou_bounded("12345", 12, 20000, &x);
assert_se(r == 0);
assert_se(x == 12345);
r = safe_atou_bounded("12", 12, 20000, &x);
assert_se(r == 0);
assert_se(x == 12);
r = safe_atou_bounded("20000", 12, 20000, &x);
assert_se(r == 0);
assert_se(x == 20000);
r = safe_atou_bounded("-1", 12, 20000, &x);
assert_se(r == -ERANGE);
r = safe_atou_bounded("11", 12, 20000, &x);
assert_se(r == -ERANGE);
r = safe_atou_bounded("20001", 12, 20000, &x);
assert_se(r == -ERANGE);
}
TEST(safe_atolli) { TEST(safe_atolli) {
int r; int r;
long long l; long long l;