]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: Add SuppressInterfaceGroup= into routing policy 21235/head
authorSlava Bacherikov <slava@bacher09.org>
Thu, 4 Nov 2021 16:54:49 +0000 (18:54 +0200)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 15 Nov 2021 16:54:07 +0000 (01:54 +0900)
This adds SuppressInterfaceGroup= option in the [RoutingPolicyRule] section
which has the same semantics as suppress_ifgroup in `ip rule` command.

man/systemd.network.xml
src/network/networkd-network-gperf.gperf
src/network/networkd-routing-policy-rule.c
src/network/networkd-routing-policy-rule.h
test/fuzz/fuzz-network-parser/directives.network
test/fuzz/fuzz-unit-file/directives-all.service

index dea600fbd6bffe533f4453aaf50f4bf8d495b1b4..1bedc5b18bb629953ce0caea1ab0a8c40915912e 100644 (file)
@@ -1282,6 +1282,14 @@ Table=1234</programlisting></para>
             unset.</para>
           </listitem>
         </varlistentry>
+        <varlistentry>
+          <term><varname>SuppressInterfaceGroup=</varname></term>
+          <listitem>
+            <para>Takes an integer in the range 0…2147483647 and rejects routing decisions that have
+            an interface with the same group id. It has the same meaning as
+            <option>suppress_ifgroup</option> in <command>ip rule</command>. Defaults to unset.</para>
+          </listitem>
+        </varlistentry>
         <varlistentry>
           <term><varname>Type=</varname></term>
           <listitem>
index 515a5b5bd951980d126b3422f5239cd2bcf958dd..525d0158bcc9ec916ed9780e29b0f11cd557b68f 100644 (file)
@@ -171,6 +171,7 @@ RoutingPolicyRule.DestinationPort,           config_parse_routing_policy_rule_po
 RoutingPolicyRule.InvertRule,                config_parse_routing_policy_rule_invert,                  0,                             0
 RoutingPolicyRule.Family,                    config_parse_routing_policy_rule_family,                  0,                             0
 RoutingPolicyRule.User,                      config_parse_routing_policy_rule_uid_range,               0,                             0
+RoutingPolicyRule.SuppressInterfaceGroup,    config_parse_routing_policy_rule_suppress_ifgroup,        0,                             0
 RoutingPolicyRule.SuppressPrefixLength,      config_parse_routing_policy_rule_suppress_prefixlen,      0,                             0
 RoutingPolicyRule.Type,                      config_parse_routing_policy_rule_type,                    0,                             0
 Route.Gateway,                               config_parse_gateway,                                     0,                             0
index 35808b10f72405496343747213811a5f93b42358..cbde514c98c44f467e926045c19c524a8ba304b1 100644 (file)
@@ -65,6 +65,7 @@ static int routing_policy_rule_new(RoutingPolicyRule **ret) {
                 .uid_range.start = UID_INVALID,
                 .uid_range.end = UID_INVALID,
                 .suppress_prefixlen = -1,
+                .suppress_ifgroup = -1,
                 .protocol = RTPROT_UNSPEC,
                 .type = FR_ACT_TO_TBL,
         };
@@ -165,6 +166,7 @@ void routing_policy_rule_hash_func(const RoutingPolicyRule *rule, struct siphash
                 siphash24_compress(&rule->priority, sizeof(rule->priority), state);
                 siphash24_compress(&rule->table, sizeof(rule->table), state);
                 siphash24_compress(&rule->suppress_prefixlen, sizeof(rule->suppress_prefixlen), state);
+                siphash24_compress(&rule->suppress_ifgroup, sizeof(rule->suppress_ifgroup), state);
 
                 siphash24_compress(&rule->ipproto, sizeof(rule->ipproto), state);
                 siphash24_compress(&rule->protocol, sizeof(rule->protocol), state);
@@ -240,6 +242,10 @@ int routing_policy_rule_compare_func(const RoutingPolicyRule *a, const RoutingPo
                 if (r != 0)
                         return r;
 
+                r = CMP(a->suppress_ifgroup, b->suppress_ifgroup);
+                if (r != 0)
+                        return r;
+
                 r = CMP(a->ipproto, b->ipproto);
                 if (r != 0)
                         return r;
@@ -534,6 +540,12 @@ static int routing_policy_rule_set_netlink_message(const RoutingPolicyRule *rule
                         return log_link_error_errno(link, r, "Could not append FRA_SUPPRESS_PREFIXLEN attribute: %m");
         }
 
+        if (rule->suppress_ifgroup >= 0) {
+                r = sd_netlink_message_append_u32(m, FRA_SUPPRESS_IFGROUP, (uint32_t) rule->suppress_ifgroup);
+                if (r < 0)
+                        return log_link_error_errno(link, r, "Could not append FRA_SUPPRESS_IFGROUP attribute: %m");
+        }
+
         r = sd_rtnl_message_routing_policy_rule_set_fib_type(m, rule->type);
         if (r < 0)
                 return log_link_error_errno(link, r, "Could not append FIB rule type attribute: %m");
@@ -855,11 +867,11 @@ int request_process_routing_policy_rule(Request *req) {
 }
 
 static const RoutingPolicyRule kernel_rules[] = {
-        { .family = AF_INET,  .priority_set = true, .priority = 0,     .table = RT_TABLE_LOCAL,   .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
-        { .family = AF_INET,  .priority_set = true, .priority = 32766, .table = RT_TABLE_MAIN,    .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
-        { .family = AF_INET,  .priority_set = true, .priority = 32767, .table = RT_TABLE_DEFAULT, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
-        { .family = AF_INET6, .priority_set = true, .priority = 0,     .table = RT_TABLE_LOCAL,   .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
-        { .family = AF_INET6, .priority_set = true, .priority = 32766, .table = RT_TABLE_MAIN,    .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
+        { .family = AF_INET,  .priority_set = true, .priority = 0,     .table = RT_TABLE_LOCAL,   .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, .suppress_ifgroup = -1, },
+        { .family = AF_INET,  .priority_set = true, .priority = 32766, .table = RT_TABLE_MAIN,    .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, .suppress_ifgroup = -1, },
+        { .family = AF_INET,  .priority_set = true, .priority = 32767, .table = RT_TABLE_DEFAULT, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, .suppress_ifgroup = -1, },
+        { .family = AF_INET6, .priority_set = true, .priority = 0,     .table = RT_TABLE_LOCAL,   .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, .suppress_ifgroup = -1, },
+        { .family = AF_INET6, .priority_set = true, .priority = 32766, .table = RT_TABLE_MAIN,    .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, .suppress_ifgroup = -1, },
 };
 
 static bool routing_policy_rule_is_created_by_kernel(const RoutingPolicyRule *rule) {
@@ -1049,8 +1061,28 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man
                 log_warning_errno(r, "rtnl: could not get FRA_SUPPRESS_PREFIXLEN attribute, ignoring: %m");
                 return 0;
         }
-        if (r >= 0)
-                tmp->suppress_prefixlen = (int) suppress_prefixlen;
+        if (r >= 0) {
+                /* kernel does not limit this value, but we do. */
+                if (suppress_prefixlen > 128) {
+                        log_warning("rtnl: received invalid FRA_SUPPRESS_PREFIXLEN attribute value %"PRIu32", ignoring.", suppress_prefixlen);
+                        return 0;
+                }
+                tmp->suppress_prefixlen = (int32_t) suppress_prefixlen;
+        }
+
+        uint32_t suppress_ifgroup;
+        r = sd_netlink_message_read_u32(message, FRA_SUPPRESS_IFGROUP, &suppress_ifgroup);
+        if (r < 0 && r != -ENODATA) {
+                log_warning_errno(r, "rtnl: could not get FRA_SUPPRESS_IFGROUP attribute, ignoring: %m");
+                return 0;
+        }
+        if (r >= 0) {
+                if (suppress_ifgroup > INT32_MAX) {
+                        log_warning("rtnl: received invalid FRA_SUPPRESS_IFGROUP attribute value %"PRIu32", ignoring.", suppress_ifgroup);
+                        return 0;
+                }
+                tmp->suppress_ifgroup = (int32_t) suppress_ifgroup;
+        }
 
         if (adjust_protocol)
                 /* As .network files does not have setting to specify protocol, we can assume the
@@ -1622,6 +1654,54 @@ int config_parse_routing_policy_rule_suppress_prefixlen(
         return 0;
 }
 
+int config_parse_routing_policy_rule_suppress_ifgroup(
+                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_free_or_set_invalidp) RoutingPolicyRule *n = NULL;
+        Network *network = userdata;
+        int32_t suppress_ifgroup;
+        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 log_oom();
+
+        if (isempty(rvalue)) {
+                n->suppress_ifgroup = -1;
+                return 0;
+        }
+
+        r = safe_atoi32(rvalue, &suppress_ifgroup);
+        if (r < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Failed to parse SuppressInterfaceGroup=, ignoring assignment: %s", rvalue);
+                return 0;
+        }
+        if (suppress_ifgroup < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, 0,
+                           "Value of SuppressInterfaceGroup= must be in the range 0…2147483647, ignoring assignment: %s", rvalue);
+                return 0;
+        }
+        n->suppress_ifgroup = suppress_ifgroup;
+        TAKE_PTR(n);
+        return 0;
+}
+
 int config_parse_routing_policy_rule_type(
                 const char *unit,
                 const char *filename,
index 89f49fcb86cd1992e1a69cffab911f7dfd354666..ac65fe8af48fb8ef068f7ea171468dab9c688a4b 100644 (file)
@@ -51,6 +51,7 @@ typedef struct RoutingPolicyRule {
         struct fib_rule_uid_range uid_range;
 
         int suppress_prefixlen;
+        int32_t suppress_ifgroup;
 } RoutingPolicyRule;
 
 RoutingPolicyRule *routing_policy_rule_free(RoutingPolicyRule *rule);
@@ -88,4 +89,5 @@ CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_invert);
 CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_family);
 CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_uid_range);
 CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_suppress_prefixlen);
+CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_suppress_ifgroup);
 CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_type);
index 26ab3931e0788be2a31b2afdf27e3033d41f0a4a..5b5a4f8c60e93e3633b9c4abedd6a1718287645a 100644 (file)
@@ -315,6 +315,7 @@ IPProtocol=
 InvertRule=
 Family=
 SuppressPrefixLength=
+SuppressInterfaceGroup=
 User=
 Type=
 [IPv6SendRA]
index 37a68708f70ae214833127202dc7a68d6c2ae927..c038ed87072af29a996fef33985769465179818d 100644 (file)
@@ -561,6 +561,7 @@ Scope=
 SendHostname=
 Source=
 SuppressPrefixLength=
+SuppressInterfaceGroup=
 TCP6SegmentationOffload=
 TCPSegmentationOffload=
 TOS=