From 7e60a37d049e3b508d859f1b658cf6161526207c Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 28 Aug 2020 12:27:32 +0900 Subject: [PATCH 1/7] network: move routing_policy_rule_read_full_file() --- src/network/networkd-routing-policy-rule.c | 40 +++++++++++----------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index 36dad527d0..d379a52a2d 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -1166,26 +1166,6 @@ int config_parse_routing_policy_rule_suppress_prefixlen( return 0; } -static int routing_policy_rule_read_full_file(const char *state_file, char **ret) { - _cleanup_free_ char *s = NULL; - size_t size; - int r; - - assert(state_file); - - r = read_full_file(state_file, &s, &size); - if (r == -ENOENT) - return -ENODATA; - if (r < 0) - return r; - if (size <= 0) - return -ENODATA; - - *ret = TAKE_PTR(s); - - return size; -} - int routing_policy_serialize_rules(Set *rules, FILE *f) { RoutingPolicyRule *rule = NULL; Iterator i; @@ -1303,6 +1283,26 @@ int routing_policy_serialize_rules(Set *rules, FILE *f) { return 0; } +static int routing_policy_rule_read_full_file(const char *state_file, char **ret) { + _cleanup_free_ char *s = NULL; + size_t size; + int r; + + assert(state_file); + + r = read_full_file(state_file, &s, &size); + if (r == -ENOENT) + return -ENODATA; + if (r < 0) + return r; + if (size <= 0) + return -ENODATA; + + *ret = TAKE_PTR(s); + + return size; +} + int routing_policy_load_rules(const char *state_file, Set **rules) { _cleanup_strv_free_ char **l = NULL; _cleanup_free_ char *data = NULL; From 3c94b20dd3b897a976044ca6bf6bc0a0f8c9d7a6 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 4 Sep 2020 08:44:14 +0900 Subject: [PATCH 2/7] network: downgrade error level when the error is ignored --- src/network/networkd-routing-policy-rule.c | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index d379a52a2d..36b6138aba 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -1360,39 +1360,39 @@ int routing_policy_load_rules(const char *state_file, Set **rules) { r = in_addr_prefix_from_string_auto(b, &rule->family, buffer, prefixlen); if (r < 0) { - log_error_errno(r, "RPDB rule prefix is invalid, ignoring assignment: %s", b); + log_warning_errno(r, "RPDB rule prefix is invalid, ignoring assignment: %s", b); continue; } } else if (streq(a, "family")) { r = af_from_name(b); if (r < 0) { - log_error_errno(r, "Failed to parse RPDB rule family, ignoring: %s", b); + log_warning_errno(r, "Failed to parse RPDB rule family, ignoring: %s", b); continue; } rule->family = r; } else if (streq(a, "tos")) { r = safe_atou8(b, &rule->tos); if (r < 0) { - log_error_errno(r, "Failed to parse RPDB rule TOS, ignoring: %s", b); + log_warning_errno(r, "Failed to parse RPDB rule TOS, ignoring: %s", b); continue; } } else if (streq(a, "table")) { r = safe_atou32(b, &rule->table); if (r < 0) { - log_error_errno(r, "Failed to parse RPDB rule table, ignoring: %s", b); + log_warning_errno(r, "Failed to parse RPDB rule table, ignoring: %s", b); continue; } } else if (streq(a, "priority")) { r = safe_atou32(b, &rule->priority); if (r < 0) { - log_error_errno(r, "Failed to parse RPDB rule priority, ignoring: %s", b); + log_warning_errno(r, "Failed to parse RPDB rule priority, ignoring: %s", b); continue; } } else if (streq(a, "fwmark")) { r = parse_fwmark_fwmask(b, &rule->fwmark, &rule->fwmask); if (r < 0) { - log_error_errno(r, "Failed to parse RPDB rule firewall mark or mask, ignoring: %s", a); + log_warning_errno(r, "Failed to parse RPDB rule firewall mark or mask, ignoring: %s", a); continue; } } else if (streq(a, "iif")) { @@ -1406,13 +1406,13 @@ int routing_policy_load_rules(const char *state_file, Set **rules) { } else if (streq(a, "protocol")) { r = safe_atou8(b, &rule->protocol); if (r < 0) { - log_error_errno(r, "Failed to parse RPDB rule protocol, ignoring: %s", b); + log_warning_errno(r, "Failed to parse RPDB rule protocol, ignoring: %s", b); continue; } } else if (streq(a, "sourceport")) { r = parse_ip_port_range(b, &low, &high); if (r < 0) { - log_error_errno(r, "Invalid routing policy rule source port range, ignoring assignment: '%s'", b); + log_warning_errno(r, "Invalid routing policy rule source port range, ignoring assignment: '%s'", b); continue; } @@ -1421,7 +1421,7 @@ int routing_policy_load_rules(const char *state_file, Set **rules) { } else if (streq(a, "destinationport")) { r = parse_ip_port_range(b, &low, &high); if (r < 0) { - log_error_errno(r, "Invalid routing policy rule destination port range, ignoring assignment: '%s'", b); + log_warning_errno(r, "Invalid routing policy rule destination port range, ignoring assignment: '%s'", b); continue; } @@ -1432,7 +1432,7 @@ int routing_policy_load_rules(const char *state_file, Set **rules) { r = parse_uid_range(b, &lower, &upper); if (r < 0) { - log_error_errno(r, "Invalid routing policy rule uid range, ignoring assignment: '%s'", b); + log_warning_errno(r, "Invalid routing policy rule uid range, ignoring assignment: '%s'", b); continue; } @@ -1441,11 +1441,11 @@ int routing_policy_load_rules(const char *state_file, Set **rules) { } else if (streq(a, "suppress_prefixlen")) { r = parse_ip_prefix_length(b, &rule->suppress_prefixlen); if (r == -ERANGE) { - log_error_errno(r, "Prefix length outside of valid range 0-128, ignoring: %s", b); + log_warning_errno(r, "Prefix length outside of valid range 0-128, ignoring: %s", b); continue; } if (r < 0) { - log_error_errno(r, "Failed to parse RPDB rule suppress_prefixlen, ignoring: %s", b); + log_warning_errno(r, "Failed to parse RPDB rule suppress_prefixlen, ignoring: %s", b); continue; } } From 1680b11df49039c312584feb8418f0a31b8bea30 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 28 Aug 2020 12:34:36 +0900 Subject: [PATCH 3/7] network: add whitespace after family= and priority= in serialized routing policy rule This also makes priority= serialized only when its value is non-zero. --- src/network/networkd-routing-policy-rule.c | 19 ++++++++++++------- src/network/test-routing-policy-rule.c | 14 +++++++------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index 36b6138aba..bb5648cc53 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -1202,10 +1202,12 @@ int routing_policy_serialize_rules(Set *rules, FILE *f) { } family_str = af_to_name(rule->family); - if (family_str) - fprintf(f, "%sfamily=%s", - space ? " " : "", - family_str); + if (family_str) { + fprintf(f, "%sfamily=%s", + space ? " " : "", + family_str); + space = true; + } if (rule->tos != 0) { fprintf(f, "%stos=%hhu", @@ -1214,9 +1216,12 @@ int routing_policy_serialize_rules(Set *rules, FILE *f) { space = true; } - fprintf(f, "%spriority=%"PRIu32, - space ? " " : "", - rule->priority); + if (rule->priority != 0) { + fprintf(f, "%spriority=%"PRIu32, + space ? " " : "", + rule->priority); + space = true; + } if (rule->fwmark != 0) { fprintf(f, "%sfwmark=%"PRIu32"/%"PRIu32, diff --git a/src/network/test-routing-policy-rule.c b/src/network/test-routing-policy-rule.c index d84d746c3f..b539e11dad 100644 --- a/src/network/test-routing-policy-rule.c +++ b/src/network/test-routing-policy-rule.c @@ -62,31 +62,31 @@ int main(int argc, char **argv) { test_setup_logging(LOG_DEBUG); test_rule_serialization("basic parsing", - "RULE=from=1.2.3.4/32 to=2.3.4.5/32 family=AF_INET tos=5 priority=0 fwmark=1/2 table=10", NULL); + "RULE=from=1.2.3.4/32 to=2.3.4.5/32 family=AF_INET tos=5 priority=10 fwmark=1/2 table=10", NULL); test_rule_serialization("ignored values", "RULE=something=to=ignore from=1.2.3.4/32 from=1.2.3.4/32" " \t to=2.3.4.5/24 to=2.3.4.5/32 tos=5 fwmark=2 fwmark=1 table=10 table=20", "RULE=from=1.2.3.4/32" - " to=2.3.4.5/32 family=AF_INET tos=5 priority=0 fwmark=1/0 table=20"); + " to=2.3.4.5/32 family=AF_INET tos=5 fwmark=1/0 table=20"); test_rule_serialization("ipv6", - "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 priority=0 table=6", NULL); + "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 table=6", NULL); - assert_se(asprintf(&p, "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 priority=0 table=%d", RT_TABLE_MAIN) >= 0); + assert_se(asprintf(&p, "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 table=%d", RT_TABLE_MAIN) >= 0); test_rule_serialization("default table", "RULE=from=1::2/64 to=2::3/64", p); test_rule_serialization("incoming interface", "RULE=from=1::2/64 to=2::3/64 table=1 iif=lo", - "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 priority=0 iif=lo table=1"); + "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 iif=lo table=1"); test_rule_serialization("outgoing interface", - "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 priority=0 oif=eth0 table=1", NULL); + "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 oif=eth0 table=1", NULL); test_rule_serialization("freeing interface names", "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 iif=e0 iif=e1 oif=e0 oif=e1 table=1", - "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 priority=0 iif=e1 oif=e1 table=1"); + "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 iif=e1 oif=e1 table=1"); return 0; } From d0ac05613b6bbf226b7cc7a9831226dd6733e2cd Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 28 Aug 2020 12:47:44 +0900 Subject: [PATCH 4/7] network: serialize InvertRule= in [RoutingPolicyRule] --- src/network/networkd-routing-policy-rule.c | 10 +++++++++- src/network/test-routing-policy-rule.c | 15 +++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index bb5648cc53..4befc2f498 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -1280,8 +1280,9 @@ int routing_policy_serialize_rules(Set *rules, FILE *f) { space = true; } - fprintf(f, "%stable=%"PRIu32 "\n", + fprintf(f, "%sinvert_rule=%s table=%"PRIu32"\n", space ? " " : "", + yes_no(rule->invert_rule), rule->table); } @@ -1453,6 +1454,13 @@ int routing_policy_load_rules(const char *state_file, Set **rules) { log_warning_errno(r, "Failed to parse RPDB rule suppress_prefixlen, ignoring: %s", b); continue; } + } else if (streq(a, "invert_rule")) { + r = parse_boolean(b); + if (r < 0) { + log_warning_errno(r, "Failed to parse RPDB rule invert_rule, ignoring: %s", b); + continue; + } + rule->invert_rule = r; } } diff --git a/src/network/test-routing-policy-rule.c b/src/network/test-routing-policy-rule.c index b539e11dad..0a0434aaab 100644 --- a/src/network/test-routing-policy-rule.c +++ b/src/network/test-routing-policy-rule.c @@ -62,31 +62,30 @@ int main(int argc, char **argv) { test_setup_logging(LOG_DEBUG); test_rule_serialization("basic parsing", - "RULE=from=1.2.3.4/32 to=2.3.4.5/32 family=AF_INET tos=5 priority=10 fwmark=1/2 table=10", NULL); + "RULE=from=1.2.3.4/32 to=2.3.4.5/32 family=AF_INET tos=5 priority=10 fwmark=1/2 invert_rule=yes table=10", NULL); test_rule_serialization("ignored values", "RULE=something=to=ignore from=1.2.3.4/32 from=1.2.3.4/32" " \t to=2.3.4.5/24 to=2.3.4.5/32 tos=5 fwmark=2 fwmark=1 table=10 table=20", - "RULE=from=1.2.3.4/32" - " to=2.3.4.5/32 family=AF_INET tos=5 fwmark=1/0 table=20"); + "RULE=from=1.2.3.4/32 to=2.3.4.5/32 family=AF_INET tos=5 fwmark=1/0 invert_rule=no table=20"); test_rule_serialization("ipv6", - "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 table=6", NULL); + "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 invert_rule=yes table=6", NULL); - assert_se(asprintf(&p, "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 table=%d", RT_TABLE_MAIN) >= 0); + assert_se(asprintf(&p, "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 invert_rule=no table=%d", RT_TABLE_MAIN) >= 0); test_rule_serialization("default table", "RULE=from=1::2/64 to=2::3/64", p); test_rule_serialization("incoming interface", "RULE=from=1::2/64 to=2::3/64 table=1 iif=lo", - "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 iif=lo table=1"); + "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 iif=lo invert_rule=no table=1"); test_rule_serialization("outgoing interface", - "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 oif=eth0 table=1", NULL); + "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 oif=eth0 invert_rule=no table=1", NULL); test_rule_serialization("freeing interface names", "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 iif=e0 iif=e1 oif=e0 oif=e1 table=1", - "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 iif=e1 oif=e1 table=1"); + "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 iif=e1 oif=e1 invert_rule=no table=1"); return 0; } From 9d6282d1205be45768460ccc4ba2ae5d8397dbde Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 28 Aug 2020 12:53:08 +0900 Subject: [PATCH 5/7] network: do not reallocate buffer --- src/network/networkd-routing-policy-rule.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index 4befc2f498..e7e89db97e 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -1340,17 +1340,21 @@ int routing_policy_load_rules(const char *state_file, Set **rules) { return r; for (;;) { - _cleanup_free_ char *word = NULL, *a = NULL, *b = NULL; + _cleanup_free_ char *a = NULL; + char *b; - r = extract_first_word(&p, &word, NULL, 0); + r = extract_first_word(&p, &a, NULL, 0); if (r < 0) return r; if (r == 0) break; - r = split_pair(word, "=", &a, &b); - if (r < 0) + b = strchr(a, '='); + if (!b) { + log_warning_errno(r, "Failed to parse RPDB rule, ignoring: %s", a); continue; + } + *b++ = '\0'; if (STR_IN_SET(a, "from", "to")) { union in_addr_union *buffer; From f405179d659bd27e29966ae1bccd7f7586400e5a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 28 Aug 2020 12:58:49 +0900 Subject: [PATCH 6/7] network: honor already specified family when parsing from= or to= in serialized rule --- src/network/networkd-routing-policy-rule.c | 46 ++++++++++++---------- src/network/test-routing-policy-rule.c | 18 +++++---- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index e7e89db97e..d72246c20f 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -1175,17 +1175,25 @@ int routing_policy_serialize_rules(Set *rules, FILE *f) { SET_FOREACH(rule, rules, i) { _cleanup_free_ char *from_str = NULL, *to_str = NULL; - bool space = false; const char *family_str; + bool space = false; fputs("RULE=", f); + family_str = af_to_name(rule->family); + if (family_str) { + fprintf(f, "family=%s", + family_str); + space = true; + } + if (!in_addr_is_null(rule->family, &rule->from)) { r = in_addr_to_string(rule->family, &rule->from, &from_str); if (r < 0) return r; - fprintf(f, "from=%s/%hhu", + fprintf(f, "%sfrom=%s/%hhu", + space ? " " : "", from_str, rule->from_prefixlen); space = true; } @@ -1201,14 +1209,6 @@ int routing_policy_serialize_rules(Set *rules, FILE *f) { space = true; } - family_str = af_to_name(rule->family); - if (family_str) { - fprintf(f, "%sfamily=%s", - space ? " " : "", - family_str); - space = true; - } - if (rule->tos != 0) { fprintf(f, "%stos=%hhu", space ? " " : "", @@ -1356,7 +1356,18 @@ int routing_policy_load_rules(const char *state_file, Set **rules) { } *b++ = '\0'; - if (STR_IN_SET(a, "from", "to")) { + if (streq(a, "family")) { + r = af_from_name(b); + if (r < 0) { + log_warning_errno(r, "Failed to parse RPDB rule family, ignoring: %s", b); + continue; + } + if (rule->family != AF_UNSPEC && rule->family != r) { + log_warning("RPDB rule family is already specified, ignoring assignment: %s", b); + continue; + } + rule->family = r; + } if (STR_IN_SET(a, "from", "to")) { union in_addr_union *buffer; uint8_t *prefixlen; @@ -1368,19 +1379,14 @@ int routing_policy_load_rules(const char *state_file, Set **rules) { prefixlen = &rule->from_prefixlen; } - r = in_addr_prefix_from_string_auto(b, &rule->family, buffer, prefixlen); + if (rule->family == AF_UNSPEC) + r = in_addr_prefix_from_string_auto(b, &rule->family, buffer, prefixlen); + else + r = in_addr_prefix_from_string(b, rule->family, buffer, prefixlen); if (r < 0) { log_warning_errno(r, "RPDB rule prefix is invalid, ignoring assignment: %s", b); continue; } - - } else if (streq(a, "family")) { - r = af_from_name(b); - if (r < 0) { - log_warning_errno(r, "Failed to parse RPDB rule family, ignoring: %s", b); - continue; - } - rule->family = r; } else if (streq(a, "tos")) { r = safe_atou8(b, &rule->tos); if (r < 0) { diff --git a/src/network/test-routing-policy-rule.c b/src/network/test-routing-policy-rule.c index 0a0434aaab..85924bc0c9 100644 --- a/src/network/test-routing-policy-rule.c +++ b/src/network/test-routing-policy-rule.c @@ -62,30 +62,34 @@ int main(int argc, char **argv) { test_setup_logging(LOG_DEBUG); test_rule_serialization("basic parsing", - "RULE=from=1.2.3.4/32 to=2.3.4.5/32 family=AF_INET tos=5 priority=10 fwmark=1/2 invert_rule=yes table=10", NULL); + "RULE=family=AF_INET from=1.2.3.4/32 to=2.3.4.5/32 tos=5 priority=10 fwmark=1/2 invert_rule=yes table=10", NULL); test_rule_serialization("ignored values", "RULE=something=to=ignore from=1.2.3.4/32 from=1.2.3.4/32" " \t to=2.3.4.5/24 to=2.3.4.5/32 tos=5 fwmark=2 fwmark=1 table=10 table=20", - "RULE=from=1.2.3.4/32 to=2.3.4.5/32 family=AF_INET tos=5 fwmark=1/0 invert_rule=no table=20"); + "RULE=family=AF_INET from=1.2.3.4/32 to=2.3.4.5/32 tos=5 fwmark=1/0 invert_rule=no table=20"); test_rule_serialization("ipv6", - "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 invert_rule=yes table=6", NULL); + "RULE=family=AF_INET6 from=1::2/64 to=2::3/64 invert_rule=yes table=6", NULL); - assert_se(asprintf(&p, "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 invert_rule=no table=%d", RT_TABLE_MAIN) >= 0); + assert_se(asprintf(&p, "RULE=family=AF_INET6 from=1::2/64 to=2::3/64 invert_rule=no table=%d", RT_TABLE_MAIN) >= 0); test_rule_serialization("default table", "RULE=from=1::2/64 to=2::3/64", p); test_rule_serialization("incoming interface", "RULE=from=1::2/64 to=2::3/64 table=1 iif=lo", - "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 iif=lo invert_rule=no table=1"); + "RULE=family=AF_INET6 from=1::2/64 to=2::3/64 iif=lo invert_rule=no table=1"); test_rule_serialization("outgoing interface", - "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 oif=eth0 invert_rule=no table=1", NULL); + "RULE=family=AF_INET6 from=1::2/64 to=2::3/64 oif=eth0 invert_rule=no table=1", NULL); test_rule_serialization("freeing interface names", "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 iif=e0 iif=e1 oif=e0 oif=e1 table=1", - "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 iif=e1 oif=e1 invert_rule=no table=1"); + "RULE=family=AF_INET6 from=1::2/64 to=2::3/64 iif=e1 oif=e1 invert_rule=no table=1"); + + test_rule_serialization("ignoring invalid family", + "RULE=from=1::2/64 to=2::3/64 family=AF_UNSEPC family=AF_INET table=1", + "RULE=family=AF_INET6 from=1::2/64 to=2::3/64 invert_rule=no table=1"); return 0; } From 5c72a6d5d3d72bc5b7cd6c3f566b0ed7f985b6dc Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 28 Aug 2020 13:00:25 +0900 Subject: [PATCH 7/7] network: logs about unknown key --- src/network/networkd-routing-policy-rule.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index d72246c20f..d4950540be 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -1471,7 +1471,8 @@ int routing_policy_load_rules(const char *state_file, Set **rules) { continue; } rule->invert_rule = r; - } + } else + log_warning("Unknown RPDB rule, ignoring: %s", a); } r = set_ensure_put(rules, &routing_policy_rule_hash_ops, rule);