]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: drop sections contain invalid settings in network_verify()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 1 Mar 2019 04:27:47 +0000 (13:27 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 13 Mar 2019 02:59:18 +0000 (11:59 +0900)
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().

18 files changed:
src/network/networkd-address-label.c
src/network/networkd-address-label.h
src/network/networkd-address.c
src/network/networkd-address.h
src/network/networkd-fdb.c
src/network/networkd-fdb.h
src/network/networkd-ipv6-proxy-ndp.h
src/network/networkd-neighbor.c
src/network/networkd-neighbor.h
src/network/networkd-network.c
src/network/networkd-radv.c
src/network/networkd-radv.h
src/network/networkd-route.c
src/network/networkd-route.h
src/network/networkd-routing-policy-rule.c
src/network/networkd-routing-policy-rule.h
src/network/networkd-util.h
src/network/test-networkd-conf.c

index 94a12f8bfe7f868bc825fef7f04d63115b767c6b..ab738448c52bdc1c1e6775bdd183ef3491663427 100644 (file)
@@ -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;
index 6922cb0faf85241fc4e2a30822106d7c780afe61..595072a17e6fc5992e9076e1e6536b319becd951 100644 (file)
@@ -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);
 
index 06b6b3d20d94018e7aeee7790536e6a5a653506d..1a9ba4223cd93b187ea196674afe8f092737c426 100644 (file)
@@ -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;
+}
index 57d82f82c3955b6591a71a3740d07ab7b61d575a..455985d225263e8063bc60c26079881ebbc5bf03 100644 (file)
@@ -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);
index 02724938ae86ea2a3cf4e303a76270fe808918d2..fa13949538134612996322df53e83d0d93c3a2e6 100644 (file)
@@ -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);
index c0ef27d7d7c6803637582a187ec8bc31a779a7c1..6b7da2e7413598d399fd508a40e4452baa33f7b1 100644 (file)
@@ -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);
index 4ce5de8d69c51a7cb80995ba140bf8ccad209088..d6666beab5ce76eeec9eb26b013b38977bb2a367 100644 (file)
@@ -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);
index 713bad2bba3562a945a7555b4b2d6ef7ba566135..d0275fdd3eafac55f6958a37043cb0141c8821a6 100644 (file)
@@ -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);
index 094bf7977edde5e8fcf0fa381e204405a1a981c3..f591f0b03f3f97a85710026d1d3263e26d10db30 100644 (file)
@@ -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);
 
index 81d6d35c7c917c9597f4a22dcf3ccc2398e4d4cd..027e076c3463b3b3145634ec036acfec042a123b 100644 (file)
@@ -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;
 }
index 3de969764ebccb993154e441566c8d8e1d247b7a..8cb14b588cfbd5a7ab4f0c4e93e9697f5219c0e8 100644 (file)
@@ -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;
 
index ebf6d7299b09533ebac5ff75d109ac8db80a26e5..3192bb8b6c8db04cd64c03be46f2186af07c9e17 100644 (file)
@@ -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);
index 3eb807c9f83b44bae2e5575bee40eb89f440f3bb..379077cbfde9c5b17303de832f5228fb9d897c73 100644 (file)
@@ -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;
+}
index c19b7aa3a73b99ba390536e5054e8f6cc8c7f532..1e8320fdc087814ca3c74af89a3f10aeb0c548a4 100644 (file)
@@ -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);
 
index ae94272781e29223cca010c9acd1d0d8744cb1c4..f6253215ed8869885663811917d636312d2a8c66 100644 (file)
@@ -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;
 
index b35126e2cfd1a2be7252c73d5cba7709801df35c..e1bd78f80953654f004bc47d62602aaa9da7be11 100644 (file)
@@ -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);
index d360035b147d325d08e8034dbe30b1459993fd92..a49e2893511ed73381a84e7e6f6a2b13aa1f3639 100644 (file)
@@ -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);
index 86d4e7e733fa684125f1bd8020e7631aa276fa1e..3adfdab2bf8442388dabb19fc72be2bb1cd06625 100644 (file)
@@ -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);