From 8b220643b1e5146c39ca2c07c0c239e3085bca44 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Mon, 3 Dec 2018 18:25:30 +0530 Subject: [PATCH] networkd: RPDB rule - add support to configure inverted rule. Closes #10706 --- man/systemd.network.xml | 6 +++ src/libsystemd/sd-netlink/rtnl-message.c | 26 +++++++++++ src/network/networkd-network-gperf.gperf | 1 + src/network/networkd-routing-policy-rule.c | 45 +++++++++++++++++++ src/network/networkd-routing-policy-rule.h | 3 ++ src/systemd/sd-netlink.h | 2 + .../fuzz-network-parser/directives.network | 1 + test/fuzz/fuzz-unit-file/directives.service | 1 + 8 files changed, 85 insertions(+) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 229449c5ac5..ceb0788d711 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -1015,6 +1015,12 @@ Defaults to unset. + + InvertRule= + + A boolean. Specifies wheather the rule to be inverted. Defaults to false. + + diff --git a/src/libsystemd/sd-netlink/rtnl-message.c b/src/libsystemd/sd-netlink/rtnl-message.c index 4416e1720cb..2d4d00e0eb1 100644 --- a/src/libsystemd/sd-netlink/rtnl-message.c +++ b/src/libsystemd/sd-netlink/rtnl-message.c @@ -852,6 +852,32 @@ int sd_rtnl_message_routing_policy_rule_get_table(sd_netlink_message *m, unsigne return 0; } +int sd_rtnl_message_routing_policy_rule_set_flags(sd_netlink_message *m, unsigned flags) { + struct rtmsg *routing_policy_rule; + + assert_return(m, -EINVAL); + assert_return(m->hdr, -EINVAL); + assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL); + + routing_policy_rule = NLMSG_DATA(m->hdr); + routing_policy_rule->rtm_flags |= flags; + + return 0; +} + +int sd_rtnl_message_routing_policy_rule_get_flags(sd_netlink_message *m, unsigned *flags) { + struct rtmsg *routing_policy_rule; + + assert_return(m, -EINVAL); + assert_return(m->hdr, -EINVAL); + assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL); + + routing_policy_rule = NLMSG_DATA(m->hdr); + *flags = routing_policy_rule->rtm_flags; + + return 0; +} + int sd_rtnl_message_routing_policy_rule_set_rtm_type(sd_netlink_message *m, unsigned char type) { struct rtmsg *routing_policy_rule; diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index ed15d221785..61c2e55fec8 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -104,6 +104,7 @@ RoutingPolicyRule.OutgoingInterface, config_parse_routing_policy_rule_device, RoutingPolicyRule.IPProtocol, config_parse_routing_policy_rule_ip_protocol, 0, 0 RoutingPolicyRule.SourcePort, config_parse_routing_policy_rule_port_range, 0, 0 RoutingPolicyRule.DestinationPort, config_parse_routing_policy_rule_port_range, 0, 0 +RoutingPolicyRule.InvertRule, config_parse_routing_policy_rule_invert, 0, 0 Route.Gateway, config_parse_gateway, 0, 0 Route.Destination, config_parse_destination, 0, 0 Route.Source, config_parse_destination, 0, 0 diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index 96013e7026e..2dc78622cec 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -588,6 +588,12 @@ int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, link_netl return log_error_errno(r, "Could not append FRA_DPORT_RANGE attribute: %m"); } + if (rule->invert_rule) { + r = sd_rtnl_message_routing_policy_rule_set_flags(m, FIB_RULE_INVERT); + if (r < 0) + return log_error_errno(r, "Could not append FIB_RULE_INVERT attribute: %m"); + } + rule->link = link; r = netlink_call_async(link->manager->rtnl, NULL, m, @@ -959,6 +965,45 @@ int config_parse_routing_policy_rule_ip_protocol( return 0; } +int config_parse_routing_policy_rule_invert( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + _cleanup_(routing_policy_rule_freep) RoutingPolicyRule *n = NULL; + Network *network = userdata; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = routing_policy_rule_new_static(network, filename, section_line, &n); + if (r < 0) + return r; + + r = parse_boolean(rvalue); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse RPDB rule invert, ignoring: %s", rvalue); + return 0; + } + + n->invert_rule = r; + + n = NULL; + + return 0; +} + static int routing_policy_rule_read_full_file(const char *state_file, char **ret) { _cleanup_free_ char *s = NULL; size_t size; diff --git a/src/network/networkd-routing-policy-rule.h b/src/network/networkd-routing-policy-rule.h index 0e4215bffdc..b35126e2cfd 100644 --- a/src/network/networkd-routing-policy-rule.h +++ b/src/network/networkd-routing-policy-rule.h @@ -25,6 +25,8 @@ struct RoutingPolicyRule { Link *link; NetworkConfigSection *section; + bool invert_rule; + uint8_t tos; uint8_t protocol; @@ -79,3 +81,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_priority); CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_device); CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_port_range); CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_ip_protocol); +CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_invert); diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h index 20bff2838e2..30be5b113ca 100644 --- a/src/systemd/sd-netlink.h +++ b/src/systemd/sd-netlink.h @@ -179,6 +179,8 @@ int sd_rtnl_message_routing_policy_rule_set_rtm_dst_prefixlen(sd_netlink_message int sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(sd_netlink_message *m, unsigned char *len); int sd_rtnl_message_routing_policy_rule_set_rtm_type(sd_netlink_message *m, unsigned char type); int sd_rtnl_message_routing_policy_rule_get_rtm_type(sd_netlink_message *m, unsigned char *type); +int sd_rtnl_message_routing_policy_rule_set_flags(sd_netlink_message *m, unsigned flags); +int sd_rtnl_message_routing_policy_rule_get_flags(sd_netlink_message *m, unsigned *flags); /* genl */ int sd_genl_socket_open(sd_netlink **nl); diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 8ea809a7e1f..d8f556a6e5b 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -153,6 +153,7 @@ FirewallMark= SourcePort= DestinationPort= IPProtocol= +InvertRule= [IPv6PrefixDelegation] RouterPreference= DNSLifetimeSec= diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service index f454fd313ec..f5560ea2c2a 100644 --- a/test/fuzz/fuzz-unit-file/directives.service +++ b/test/fuzz/fuzz-unit-file/directives.service @@ -442,6 +442,7 @@ Independent= InitialAdvertisedReceiveWindow= InitialCongestionWindow= InputKey= +InvertRule= KernelCommandLine= KernelVersion= Key= -- 2.39.2