summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2019-03-01 13:27:47 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2019-03-13 11:59:18 +0900
commitfcbf4cb7270faa2624a0cf149f9518280e8a6714 (patch)
treeb64aa98c4b00aec29b3c3b8f216a2cb712e78178 /src/network
parent9560e5b3235e30eea2873e507d27ed00331d838c (diff)
downloadsystemd-fcbf4cb7270faa2624a0cf149f9518280e8a6714.tar.gz
systemd-fcbf4cb7270faa2624a0cf149f9518280e8a6714.tar.bz2
systemd-fcbf4cb7270faa2624a0cf149f9518280e8a6714.zip
network: drop sections contain invalid settings in network_verify()
If e.g., an [Address] section has an invalid setting, then previously assigned settings in the section is freed, and only later settings are stored. That may cause partially broken section stored in Network object. This makes if an invalid setting is found, then set 'invalid' flag instead of freeing it. And invalid sections are dropped later by network_verify().
Diffstat (limited to 'src/network')
-rw-r--r--src/network/networkd-address-label.c4
-rw-r--r--src/network/networkd-address-label.h3
-rw-r--r--src/network/networkd-address.c28
-rw-r--r--src/network/networkd-address.h4
-rw-r--r--src/network/networkd-fdb.c4
-rw-r--r--src/network/networkd-fdb.h3
-rw-r--r--src/network/networkd-ipv6-proxy-ndp.h6
-rw-r--r--src/network/networkd-neighbor.c4
-rw-r--r--src/network/networkd-neighbor.h3
-rw-r--r--src/network/networkd-network.c51
-rw-r--r--src/network/networkd-radv.c6
-rw-r--r--src/network/networkd-radv.h3
-rw-r--r--src/network/networkd-route.c54
-rw-r--r--src/network/networkd-route.h4
-rw-r--r--src/network/networkd-routing-policy-rule.c18
-rw-r--r--src/network/networkd-routing-policy-rule.h3
-rw-r--r--src/network/networkd-util.h22
-rw-r--r--src/network/test-networkd-conf.c2
18 files changed, 149 insertions, 73 deletions
diff --git a/src/network/networkd-address-label.c b/src/network/networkd-address-label.c
index 94a12f8bfe..ab738448c5 100644
--- a/src/network/networkd-address-label.c
+++ b/src/network/networkd-address-label.c
@@ -159,7 +159,7 @@ int config_parse_address_label_prefix(const char *unit,
void *data,
void *userdata) {
- _cleanup_(address_label_freep) AddressLabel *n = NULL;
+ _cleanup_(address_label_free_or_set_invalidp) AddressLabel *n = NULL;
Network *network = userdata;
int r;
@@ -196,7 +196,7 @@ int config_parse_address_label(
void *data,
void *userdata) {
- _cleanup_(address_label_freep) AddressLabel *n = NULL;
+ _cleanup_(address_label_free_or_set_invalidp) AddressLabel *n = NULL;
Network *network = userdata;
uint32_t k;
int r;
diff --git a/src/network/networkd-address-label.h b/src/network/networkd-address-label.h
index 6922cb0faf..595072a17e 100644
--- a/src/network/networkd-address-label.h
+++ b/src/network/networkd-address-label.h
@@ -11,6 +11,7 @@ typedef struct AddressLabel AddressLabel;
#include "networkd-link.h"
#include "networkd-network.h"
+#include "networkd-util.h"
typedef struct Network Network;
typedef struct Link Link;
@@ -30,7 +31,7 @@ struct AddressLabel {
void address_label_free(AddressLabel *label);
-DEFINE_TRIVIAL_CLEANUP_FUNC(AddressLabel*, address_label_free);
+DEFINE_NETWORK_SECTION_FUNCTIONS(AddressLabel, address_label_free);
int address_label_configure(AddressLabel *address, Link *link, link_netlink_message_handler_t callback, bool update);
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c
index 06b6b3d20d..1a9ba4223c 100644
--- a/src/network/networkd-address.c
+++ b/src/network/networkd-address.c
@@ -681,7 +681,7 @@ int config_parse_broadcast(
void *userdata) {
Network *network = userdata;
- _cleanup_(address_freep) Address *n = NULL;
+ _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
int r;
assert(filename);
@@ -725,7 +725,7 @@ int config_parse_address(const char *unit,
void *userdata) {
Network *network = userdata;
- _cleanup_(address_freep) Address *n = NULL;
+ _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
union in_addr_union buffer;
unsigned char prefixlen;
int r, f;
@@ -807,7 +807,7 @@ int config_parse_label(
void *data,
void *userdata) {
- _cleanup_(address_freep) Address *n = NULL;
+ _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
Network *network = userdata;
int r;
@@ -846,7 +846,7 @@ int config_parse_lifetime(const char *unit,
void *data,
void *userdata) {
Network *network = userdata;
- _cleanup_(address_freep) Address *n = NULL;
+ _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
unsigned k;
int r;
@@ -888,7 +888,7 @@ int config_parse_address_flags(const char *unit,
void *data,
void *userdata) {
Network *network = userdata;
- _cleanup_(address_freep) Address *n = NULL;
+ _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
int r;
assert(filename);
@@ -936,7 +936,7 @@ int config_parse_address_scope(const char *unit,
void *data,
void *userdata) {
Network *network = userdata;
- _cleanup_(address_freep) Address *n = NULL;
+ _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
int r;
assert(filename);
@@ -976,3 +976,19 @@ bool address_is_ready(const Address *a) {
else
return !(a->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED));
}
+
+int address_section_verify(Address *address) {
+ if (section_is_invalid(address->section))
+ return -EINVAL;
+
+ if (address->family == AF_UNSPEC) {
+ assert(address->section);
+
+ return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
+ "%s: Address section without Address= field configured. "
+ "Ignoring [Address] section from line %u.",
+ address->section->filename, address->section->line);
+ }
+
+ return 0;
+}
diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h
index 57d82f82c3..455985d225 100644
--- a/src/network/networkd-address.h
+++ b/src/network/networkd-address.h
@@ -11,6 +11,7 @@ typedef struct Address Address;
#include "networkd-link.h"
#include "networkd-network.h"
+#include "networkd-util.h"
#define CACHE_INFO_INFINITY_LIFE_TIME 0xFFFFFFFFU
@@ -57,8 +58,9 @@ int address_configure(Address *address, Link *link, link_netlink_message_handler
int address_remove(Address *address, Link *link, link_netlink_message_handler_t callback);
bool address_equal(Address *a1, Address *a2);
bool address_is_ready(const Address *a);
+int address_section_verify(Address *a);
-DEFINE_TRIVIAL_CLEANUP_FUNC(Address*, address_free);
+DEFINE_NETWORK_SECTION_FUNCTIONS(Address, address_free);
CONFIG_PARSER_PROTOTYPE(config_parse_address);
CONFIG_PARSER_PROTOTYPE(config_parse_broadcast);
diff --git a/src/network/networkd-fdb.c b/src/network/networkd-fdb.c
index 02724938ae..fa13949538 100644
--- a/src/network/networkd-fdb.c
+++ b/src/network/networkd-fdb.c
@@ -189,7 +189,7 @@ int config_parse_fdb_hwaddr(
void *userdata) {
Network *network = userdata;
- _cleanup_(fdb_entry_freep) FdbEntry *fdb_entry = NULL;
+ _cleanup_(fdb_entry_free_or_set_invalidp) FdbEntry *fdb_entry = NULL;
int r;
assert(filename);
@@ -235,7 +235,7 @@ int config_parse_fdb_vlan_id(
void *userdata) {
Network *network = userdata;
- _cleanup_(fdb_entry_freep) FdbEntry *fdb_entry = NULL;
+ _cleanup_(fdb_entry_free_or_set_invalidp) FdbEntry *fdb_entry = NULL;
int r;
assert(filename);
diff --git a/src/network/networkd-fdb.h b/src/network/networkd-fdb.h
index c0ef27d7d7..6b7da2e741 100644
--- a/src/network/networkd-fdb.h
+++ b/src/network/networkd-fdb.h
@@ -8,6 +8,7 @@
#include "conf-parser.h"
#include "list.h"
#include "macro.h"
+#include "networkd-util.h"
typedef struct Network Network;
typedef struct FdbEntry FdbEntry;
@@ -27,7 +28,7 @@ struct FdbEntry {
void fdb_entry_free(FdbEntry *fdb_entry);
int fdb_entry_configure(Link *link, FdbEntry *fdb_entry);
-DEFINE_TRIVIAL_CLEANUP_FUNC(FdbEntry*, fdb_entry_free);
+DEFINE_NETWORK_SECTION_FUNCTIONS(FdbEntry, fdb_entry_free);
CONFIG_PARSER_PROTOTYPE(config_parse_fdb_hwaddr);
CONFIG_PARSER_PROTOTYPE(config_parse_fdb_vlan_id);
diff --git a/src/network/networkd-ipv6-proxy-ndp.h b/src/network/networkd-ipv6-proxy-ndp.h
index 4ce5de8d69..d6666beab5 100644
--- a/src/network/networkd-ipv6-proxy-ndp.h
+++ b/src/network/networkd-ipv6-proxy-ndp.h
@@ -10,10 +10,10 @@ typedef struct IPv6ProxyNDPAddress IPv6ProxyNDPAddress;
typedef struct Link Link;
struct IPv6ProxyNDPAddress {
- Network *network;
- struct in6_addr in_addr;
+ Network *network;
+ struct in6_addr in_addr;
- LIST_FIELDS(IPv6ProxyNDPAddress, ipv6_proxy_ndp_addresses);
+ LIST_FIELDS(IPv6ProxyNDPAddress, ipv6_proxy_ndp_addresses);
};
void ipv6_proxy_ndp_address_free(IPv6ProxyNDPAddress *ipv6_proxy_ndp_address);
diff --git a/src/network/networkd-neighbor.c b/src/network/networkd-neighbor.c
index 713bad2bba..d0275fdd3e 100644
--- a/src/network/networkd-neighbor.c
+++ b/src/network/networkd-neighbor.c
@@ -164,7 +164,7 @@ int config_parse_neighbor_address(const char *unit,
void *userdata) {
Network *network = userdata;
- _cleanup_(neighbor_freep) Neighbor *n = NULL;
+ _cleanup_(neighbor_free_or_set_invalidp) Neighbor *n = NULL;
int r;
assert(filename);
@@ -200,7 +200,7 @@ int config_parse_neighbor_hwaddr(const char *unit,
void *userdata) {
Network *network = userdata;
- _cleanup_(neighbor_freep) Neighbor *n = NULL;
+ _cleanup_(neighbor_free_or_set_invalidp) Neighbor *n = NULL;
int r;
assert(filename);
diff --git a/src/network/networkd-neighbor.h b/src/network/networkd-neighbor.h
index 094bf7977e..f591f0b03f 100644
--- a/src/network/networkd-neighbor.h
+++ b/src/network/networkd-neighbor.h
@@ -13,6 +13,7 @@ typedef struct Neighbor Neighbor;
#include "networkd-link.h"
#include "networkd-network.h"
+#include "networkd-util.h"
struct Neighbor {
Network *network;
@@ -29,7 +30,7 @@ struct Neighbor {
void neighbor_free(Neighbor *neighbor);
-DEFINE_TRIVIAL_CLEANUP_FUNC(Neighbor*, neighbor_free);
+DEFINE_NETWORK_SECTION_FUNCTIONS(Neighbor, neighbor_free);
int neighbor_configure(Neighbor *neighbor, Link *link, link_netlink_message_handler_t callback);
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 81d6d35c7c..027e076c34 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -162,6 +162,11 @@ static uint32_t network_get_stacked_netdevs_mtu(Network *network) {
static int network_verify(Network *network) {
Address *address, *address_next;
Route *route, *route_next;
+ FdbEntry *fdb, *fdb_next;
+ Neighbor *neighbor, *neighbor_next;
+ AddressLabel *label, *label_next;
+ Prefix *prefix, *prefix_next;
+ RoutingPolicyRule *rule, *rule_next;
uint32_t mtu;
assert(network);
@@ -249,34 +254,32 @@ static int network_verify(Network *network) {
}
LIST_FOREACH_SAFE(addresses, address, address_next, network->static_addresses)
- if (address->family == AF_UNSPEC) {
- log_warning("%s: Address section without Address= field configured. "
- "Ignoring [Address] section from line %u.",
- network->filename, address->section->line);
-
+ if (address_section_verify(address) < 0)
address_free(address);
- }
-
- LIST_FOREACH_SAFE(routes, route, route_next, network->static_routes) {
- if (route->family == AF_UNSPEC) {
- log_warning("%s: Route section without Gateway=, Destination=, Source=, "
- "or PreferredSource= field configured. "
- "Ignoring [Route] section from line %u.",
- network->filename, route->section->line);
+ LIST_FOREACH_SAFE(routes, route, route_next, network->static_routes)
+ if (route_section_verify(route, network) < 0)
route_free(route);
- continue;
- }
- if (network->n_static_addresses == 0 &&
- in_addr_is_null(route->family, &route->gw) == 0 &&
- route->gateway_onlink < 0) {
- log_warning("%s: Gateway= without static address configured. "
- "Enabling GatewayOnLink= option.",
- network->filename);
- route->gateway_onlink = true;
- }
- }
+ LIST_FOREACH_SAFE(static_fdb_entries, fdb, fdb_next, network->static_fdb_entries)
+ if (section_is_invalid(fdb->section))
+ fdb_entry_free(fdb);
+
+ LIST_FOREACH_SAFE(neighbors, neighbor, neighbor_next, network->neighbors)
+ if (section_is_invalid(neighbor->section))
+ neighbor_free(neighbor);
+
+ LIST_FOREACH_SAFE(labels, label, label_next, network->address_labels)
+ if (section_is_invalid(label->section))
+ address_label_free(label);
+
+ LIST_FOREACH_SAFE(prefixes, prefix, prefix_next, network->static_prefixes)
+ if (section_is_invalid(prefix->section))
+ prefix_free(prefix);
+
+ LIST_FOREACH_SAFE(rules, rule, rule_next, network->rules)
+ if (section_is_invalid(rule->section))
+ routing_policy_rule_free(rule);
return 0;
}
diff --git a/src/network/networkd-radv.c b/src/network/networkd-radv.c
index 3de969764e..8cb14b588c 100644
--- a/src/network/networkd-radv.c
+++ b/src/network/networkd-radv.c
@@ -186,7 +186,7 @@ int config_parse_prefix(const char *unit,
void *userdata) {
Network *network = userdata;
- _cleanup_(prefix_freep) Prefix *p = NULL;
+ _cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
uint8_t prefixlen = 64;
union in_addr_union in6addr;
int r;
@@ -228,7 +228,7 @@ int config_parse_prefix_flags(const char *unit,
void *data,
void *userdata) {
Network *network = userdata;
- _cleanup_(prefix_freep) Prefix *p = NULL;
+ _cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
int r, val;
assert(filename);
@@ -272,7 +272,7 @@ int config_parse_prefix_lifetime(const char *unit,
void *data,
void *userdata) {
Network *network = userdata;
- _cleanup_(prefix_freep) Prefix *p = NULL;
+ _cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
usec_t usec;
int r;
diff --git a/src/network/networkd-radv.h b/src/network/networkd-radv.h
index ebf6d7299b..3192bb8b6c 100644
--- a/src/network/networkd-radv.h
+++ b/src/network/networkd-radv.h
@@ -8,6 +8,7 @@
#include "conf-parser.h"
#include "networkd-address.h"
#include "networkd-link.h"
+#include "networkd-util.h"
typedef struct Prefix Prefix;
@@ -23,7 +24,7 @@ struct Prefix {
int prefix_new(Prefix **ret);
void prefix_free(Prefix *prefix);
-DEFINE_TRIVIAL_CLEANUP_FUNC(Prefix*, prefix_free);
+DEFINE_NETWORK_SECTION_FUNCTIONS(Prefix, prefix_free);
CONFIG_PARSER_PROTOTYPE(config_parse_router_prefix_delegation);
CONFIG_PARSER_PROTOTYPE(config_parse_router_preference);
diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
index 3eb807c9f8..379077cbfd 100644
--- a/src/network/networkd-route.c
+++ b/src/network/networkd-route.c
@@ -678,7 +678,7 @@ int route_configure(
}
int network_add_ipv4ll_route(Network *network) {
- _cleanup_(route_freep) Route *n = NULL;
+ _cleanup_(route_free_or_set_invalidp) Route *n = NULL;
int r;
assert(network);
@@ -718,7 +718,7 @@ int config_parse_gateway(
void *userdata) {
Network *network = userdata;
- _cleanup_(route_freep) Route *n = NULL;
+ _cleanup_(route_free_or_set_invalidp) Route *n = NULL;
int r;
assert(filename);
@@ -763,7 +763,7 @@ int config_parse_preferred_src(
void *userdata) {
Network *network = userdata;
- _cleanup_(route_freep) Route *n = NULL;
+ _cleanup_(route_free_or_set_invalidp) Route *n = NULL;
int r;
assert(filename);
@@ -803,7 +803,7 @@ int config_parse_destination(
void *userdata) {
Network *network = userdata;
- _cleanup_(route_freep) Route *n = NULL;
+ _cleanup_(route_free_or_set_invalidp) Route *n = NULL;
union in_addr_union *buffer;
unsigned char *prefixlen;
int r;
@@ -854,7 +854,7 @@ int config_parse_route_priority(
void *userdata) {
Network *network = userdata;
- _cleanup_(route_freep) Route *n = NULL;
+ _cleanup_(route_free_or_set_invalidp) Route *n = NULL;
int r;
assert(filename);
@@ -891,7 +891,7 @@ int config_parse_route_scope(
void *userdata) {
Network *network = userdata;
- _cleanup_(route_freep) Route *n = NULL;
+ _cleanup_(route_free_or_set_invalidp) Route *n = NULL;
int r;
assert(filename);
@@ -931,7 +931,7 @@ int config_parse_route_table(
void *data,
void *userdata) {
- _cleanup_(route_freep) Route *n = NULL;
+ _cleanup_(route_free_or_set_invalidp) Route *n = NULL;
Network *network = userdata;
int r;
@@ -969,7 +969,7 @@ int config_parse_gateway_onlink(
void *userdata) {
Network *network = userdata;
- _cleanup_(route_freep) Route *n = NULL;
+ _cleanup_(route_free_or_set_invalidp) Route *n = NULL;
int r;
assert(filename);
@@ -1008,7 +1008,7 @@ int config_parse_ipv6_route_preference(
void *userdata) {
Network *network = userdata;
- _cleanup_(route_freep) Route *n = NULL;
+ _cleanup_(route_free_or_set_invalidp) Route *n = NULL;
int r;
r = route_new_static(network, filename, section_line, &n);
@@ -1043,7 +1043,7 @@ int config_parse_route_protocol(
void *userdata) {
Network *network = userdata;
- _cleanup_(route_freep) Route *n = NULL;
+ _cleanup_(route_free_or_set_invalidp) Route *n = NULL;
int r;
r = route_new_static(network, filename, section_line, &n);
@@ -1082,7 +1082,7 @@ int config_parse_route_type(
void *userdata) {
Network *network = userdata;
- _cleanup_(route_freep) Route *n = NULL;
+ _cleanup_(route_free_or_set_invalidp) Route *n = NULL;
int r;
r = route_new_static(network, filename, section_line, &n);
@@ -1121,7 +1121,7 @@ int config_parse_tcp_window(
void *data,
void *userdata) {
- _cleanup_(route_freep) Route *n = NULL;
+ _cleanup_(route_free_or_set_invalidp) Route *n = NULL;
Network *network = userdata;
uint64_t k;
int r;
@@ -1171,7 +1171,7 @@ int config_parse_quickack(
void *data,
void *userdata) {
- _cleanup_(route_freep) Route *n = NULL;
+ _cleanup_(route_free_or_set_invalidp) Route *n = NULL;
Network *network = userdata;
int k, r;
@@ -1210,7 +1210,7 @@ int config_parse_route_mtu(
void *userdata) {
Network *network = userdata;
- _cleanup_(route_freep) Route *n = NULL;
+ _cleanup_(route_free_or_set_invalidp) Route *n = NULL;
int r;
assert(filename);
@@ -1230,3 +1230,29 @@ int config_parse_route_mtu(
TAKE_PTR(n);
return 0;
}
+
+int route_section_verify(Route *route, Network *network) {
+ if (section_is_invalid(route->section))
+ return -EINVAL;
+
+ if (route->family == AF_UNSPEC) {
+ assert(route->section);
+
+ return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
+ "%s: Route section without Gateway=, Destination=, Source=, "
+ "or PreferredSource= field configured. "
+ "Ignoring [Route] section from line %u.",
+ route->section->filename, route->section->line);
+ }
+
+ if (network->n_static_addresses == 0 &&
+ in_addr_is_null(route->family, &route->gw) == 0 &&
+ route->gateway_onlink < 0) {
+ log_warning("%s: Gateway= without static address configured. "
+ "Enabling GatewayOnLink= option.",
+ network->filename);
+ route->gateway_onlink = true;
+ }
+
+ return 0;
+}
diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h
index c19b7aa3a7..1e8320fdc0 100644
--- a/src/network/networkd-route.h
+++ b/src/network/networkd-route.h
@@ -7,6 +7,7 @@ typedef struct Route Route;
typedef struct NetworkConfigSection NetworkConfigSection;
#include "networkd-network.h"
+#include "networkd-util.h"
struct Route {
Network *network;
@@ -55,8 +56,9 @@ void route_update(Route *route, const union in_addr_union *src, unsigned char sr
bool route_equal(Route *r1, Route *r2);
int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdata);
+int route_section_verify(Route *route, Network *network);
-DEFINE_TRIVIAL_CLEANUP_FUNC(Route*, route_free);
+DEFINE_NETWORK_SECTION_FUNCTIONS(Route, route_free);
int network_add_ipv4ll_route(Network *network);
diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c
index ae94272781..f6253215ed 100644
--- a/src/network/networkd-routing-policy-rule.c
+++ b/src/network/networkd-routing-policy-rule.c
@@ -636,7 +636,7 @@ int config_parse_routing_policy_rule_tos(
void *data,
void *userdata) {
- _cleanup_(routing_policy_rule_freep) RoutingPolicyRule *n = NULL;
+ _cleanup_(routing_policy_rule_free_or_set_invalidp) RoutingPolicyRule *n = NULL;
Network *network = userdata;
int r;
@@ -673,7 +673,7 @@ int config_parse_routing_policy_rule_priority(
void *data,
void *userdata) {
- _cleanup_(routing_policy_rule_freep) RoutingPolicyRule *n = NULL;
+ _cleanup_(routing_policy_rule_free_or_set_invalidp) RoutingPolicyRule *n = NULL;
Network *network = userdata;
int r;
@@ -710,7 +710,7 @@ int config_parse_routing_policy_rule_table(
void *data,
void *userdata) {
- _cleanup_(routing_policy_rule_freep) RoutingPolicyRule *n = NULL;
+ _cleanup_(routing_policy_rule_free_or_set_invalidp) RoutingPolicyRule *n = NULL;
Network *network = userdata;
int r;
@@ -747,7 +747,7 @@ int config_parse_routing_policy_rule_fwmark_mask(
void *data,
void *userdata) {
- _cleanup_(routing_policy_rule_freep) RoutingPolicyRule *n = NULL;
+ _cleanup_(routing_policy_rule_free_or_set_invalidp) RoutingPolicyRule *n = NULL;
Network *network = userdata;
int r;
@@ -784,7 +784,7 @@ int config_parse_routing_policy_rule_prefix(
void *data,
void *userdata) {
- _cleanup_(routing_policy_rule_freep) RoutingPolicyRule *n = NULL;
+ _cleanup_(routing_policy_rule_free_or_set_invalidp) RoutingPolicyRule *n = NULL;
Network *network = userdata;
union in_addr_union *buffer;
uint8_t *prefixlen;
@@ -831,7 +831,7 @@ int config_parse_routing_policy_rule_device(
void *data,
void *userdata) {
- _cleanup_(routing_policy_rule_freep) RoutingPolicyRule *n = NULL;
+ _cleanup_(routing_policy_rule_free_or_set_invalidp) RoutingPolicyRule *n = NULL;
Network *network = userdata;
int r;
@@ -876,7 +876,7 @@ int config_parse_routing_policy_rule_port_range(
const char *rvalue,
void *data,
void *userdata) {
- _cleanup_(routing_policy_rule_freep) RoutingPolicyRule *n = NULL;
+ _cleanup_(routing_policy_rule_free_or_set_invalidp) RoutingPolicyRule *n = NULL;
Network *network = userdata;
uint16_t low, high;
int r;
@@ -922,7 +922,7 @@ int config_parse_routing_policy_rule_ip_protocol(
void *data,
void *userdata) {
- _cleanup_(routing_policy_rule_freep) RoutingPolicyRule *n = NULL;
+ _cleanup_(routing_policy_rule_free_or_set_invalidp) RoutingPolicyRule *n = NULL;
Network *network = userdata;
int r;
@@ -961,7 +961,7 @@ int config_parse_routing_policy_rule_invert(
void *data,
void *userdata) {
- _cleanup_(routing_policy_rule_freep) RoutingPolicyRule *n = NULL;
+ _cleanup_(routing_policy_rule_free_or_set_invalidp) RoutingPolicyRule *n = NULL;
Network *network = userdata;
int r;
diff --git a/src/network/networkd-routing-policy-rule.h b/src/network/networkd-routing-policy-rule.h
index b35126e2cf..e1bd78f809 100644
--- a/src/network/networkd-routing-policy-rule.h
+++ b/src/network/networkd-routing-policy-rule.h
@@ -13,6 +13,7 @@ typedef struct RoutingPolicyRule RoutingPolicyRule;
#include "networkd-link.h"
#include "networkd-network.h"
+#include "networkd-util.h"
typedef struct Network Network;
typedef struct Link Link;
@@ -54,7 +55,7 @@ struct RoutingPolicyRule {
int routing_policy_rule_new(RoutingPolicyRule **ret);
void routing_policy_rule_free(RoutingPolicyRule *rule);
-DEFINE_TRIVIAL_CLEANUP_FUNC(RoutingPolicyRule*, routing_policy_rule_free);
+DEFINE_NETWORK_SECTION_FUNCTIONS(RoutingPolicyRule, routing_policy_rule_free);
int routing_policy_rule_configure(RoutingPolicyRule *address, Link *link, link_netlink_message_handler_t callback, bool update);
int routing_policy_rule_remove(RoutingPolicyRule *routing_policy_rule, Link *link, link_netlink_message_handler_t callback);
diff --git a/src/network/networkd-util.h b/src/network/networkd-util.h
index d360035b14..a49e289351 100644
--- a/src/network/networkd-util.h
+++ b/src/network/networkd-util.h
@@ -17,6 +17,7 @@ typedef enum AddressFamilyBoolean {
typedef struct NetworkConfigSection {
unsigned line;
+ bool invalid;
char filename[];
} NetworkConfigSection;
@@ -32,3 +33,24 @@ int network_config_section_new(const char *filename, unsigned line, NetworkConfi
void network_config_section_free(NetworkConfigSection *network);
DEFINE_TRIVIAL_CLEANUP_FUNC(NetworkConfigSection*, network_config_section_free);
extern const struct hash_ops network_config_hash_ops;
+
+static inline bool section_is_invalid(NetworkConfigSection *section) {
+ /* If this retuns false, then it does _not_ mean the section is valid. */
+
+ if (!section)
+ return false;
+
+ return section->invalid;
+}
+
+#define DEFINE_NETWORK_SECTION_FUNCTIONS(type, free_func) \
+ static inline void free_func##_or_set_invalid(type *p) { \
+ assert(p); \
+ \
+ if (p->section) \
+ p->section->invalid = true; \
+ else \
+ free_func(p); \
+ } \
+ DEFINE_TRIVIAL_CLEANUP_FUNC(type*, free_func); \
+ DEFINE_TRIVIAL_CLEANUP_FUNC(type*, free_func##_or_set_invalid);
diff --git a/src/network/test-networkd-conf.c b/src/network/test-networkd-conf.c
index 86d4e7e733..3adfdab2bf 100644
--- a/src/network/test-networkd-conf.c
+++ b/src/network/test-networkd-conf.c
@@ -173,7 +173,7 @@ static void test_config_parse_address_one(const char *rvalue, int family, unsign
assert_se(network = new0(Network, 1));
assert_se(config_parse_address("network", "filename", 1, "section", 1, "Address", 0, rvalue, network, network) == 0);
- assert_se(network->n_static_addresses == n_addresses);
+ assert_se(network->n_static_addresses == 1);
if (n_addresses > 0) {
assert_se(network->static_addresses);
assert_se(network->static_addresses->prefixlen == prefixlen);