diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index 857b01468fa..8386d214b8b 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -3,6 +3,7 @@ #include #include +#include "af-list.h" #include "alloc-util.h" #include "conf-parser.h" #include "fileio.h" @@ -989,6 +990,7 @@ 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; fputs("RULE=", f); @@ -1013,6 +1015,12 @@ 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); + if (rule->tos != 0) { fprintf(f, "%stos=%hhu", space ? " " : "", @@ -1135,6 +1143,13 @@ int routing_policy_load_rules(const char *state_file, Set **rules) { 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); + 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 57bfb6af680..0319b6db096 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 tos=5 fwmark=1/2 table=10", NULL); + "RULE=from=1.2.3.4/32 to=2.3.4.5/32 family=AF_INET tos=5 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 tos=5 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 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 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 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 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 iif=e0 iif=e1 oif=e0 oif=e1 table=1", - "RULE=from=1::2/64 to=2::3/64 iif=e1 oif=e1 table=1"); + "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"); return 0; }