]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/routing-policy-rule: support all known type of rule
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 19 Aug 2024 20:16:53 +0000 (05:16 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 20 Aug 2024 12:02:31 +0000 (21:02 +0900)
This also adds GoTo= to specify the target priority of goto rule.

Note, table was the default but could not be specified in Type=.

man/systemd.network.xml
src/network/networkd-json.c
src/network/networkd-network-gperf.gperf
src/network/networkd-routing-policy-rule.c
src/network/networkd-routing-policy-rule.h

index 0374dc7cdc0f771a747e59cad3a7fa99e6c47b9a..6273274e7a3ceac711f09a58843bd068804d0369 100644 (file)
@@ -1728,6 +1728,18 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix</programlisting>
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>GoTo=</varname></term>
+        <listitem>
+          <para>Specifies the target priority used by <literal>goto</literal> type of rule. Takes an integer
+          in the range 1…4294967295. This must be larger than the priority of this rule specified in
+          <varname>Priority=</varname>. When specified, <varname>Type=goto</varname> is implied. This is
+          mandatory when <varname>Type=goto</varname>.</para>
+
+          <xi:include href="version-info.xml" xpointer="v257"/>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>IncomingInterface=</varname></term>
         <listitem>
@@ -1853,8 +1865,10 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix</programlisting>
         <term><varname>Type=</varname></term>
         <listitem>
           <para>Specifies Routing Policy Database (RPDB) rule type. Takes one of
-          <literal>blackhole</literal>, <literal>unreachable</literal> or <literal>prohibit</literal>.
-          </para>
+          <literal>table</literal>, <literal>goto</literal>, <literal>nop</literal>,
+          <literal>blackhole</literal>, <literal>unreachable</literal>, or <literal>prohibit</literal>.
+          When <literal>goto</literal>, the target priority must be specified in <varname>GoTo=</varname>.
+          Defaults to <literal>table</literal>.</para>
 
           <xi:include href="version-info.xml" xpointer="v248"/>
         </listitem>
index 0a57e6aee09e6786966524cd5a77f26e253e47ce..4eafc62c7e481cbead0a97308d5670d2dc69e296 100644 (file)
@@ -308,7 +308,7 @@ static int routing_policy_rule_append_json(RoutingPolicyRule *rule, sd_json_vari
                         SD_JSON_BUILD_PAIR_STRING("ProtocolString", protocol),
                         SD_JSON_BUILD_PAIR_UNSIGNED("TOS", rule->tos),
                         SD_JSON_BUILD_PAIR_UNSIGNED("Type", rule->type),
-                        SD_JSON_BUILD_PAIR_STRING("TypeString", fr_act_type_full_to_string(rule->type)),
+                        SD_JSON_BUILD_PAIR_STRING("TypeString", fr_act_type_to_string(rule->type)),
                         SD_JSON_BUILD_PAIR_UNSIGNED("IPProtocol", rule->ipproto),
                         SD_JSON_BUILD_PAIR_STRING("IPProtocolString", ip_protocol_to_name(rule->ipproto)),
                         SD_JSON_BUILD_PAIR_UNSIGNED("Priority", rule->priority),
index aa849fe5353d3a42f7667f1cf1c4cab97597ea1f..b2794f9efdeb8bb8b5c2bcfc3f9e342f0ab8c383 100644 (file)
@@ -178,6 +178,7 @@ Neighbor.LinkLayerAddress,                   config_parse_neighbor_lladdr,
 Neighbor.MACAddress,                         config_parse_neighbor_lladdr,                             0,                             0 /* deprecated */
 RoutingPolicyRule.TypeOfService,             config_parse_routing_policy_rule_tos,                     0,                             0
 RoutingPolicyRule.Priority,                  config_parse_routing_policy_rule_priority,                0,                             0
+RoutingPolicyRule.GoTo,                      config_parse_routing_policy_rule_goto,                    0,                             0
 RoutingPolicyRule.Table,                     config_parse_routing_policy_rule_table,                   0,                             0
 RoutingPolicyRule.FirewallMark,              config_parse_routing_policy_rule_fwmark_mask,             0,                             0
 RoutingPolicyRule.From,                      config_parse_routing_policy_rule_prefix,                  0,                             0
index e7c048f27375fa4e3ef0129eb5a1d871426df924..44d85d000fe07b7cdfd0c2344d82d06b2e1080c8 100644 (file)
 #include "user-util.h"
 
 static const char *const fr_act_type_table[__FR_ACT_MAX] = {
-        [FR_ACT_BLACKHOLE]   = "blackhole",
-        [FR_ACT_UNREACHABLE] = "unreachable",
-        [FR_ACT_PROHIBIT]    = "prohibit",
-};
-
-static const char *const fr_act_type_full_table[__FR_ACT_MAX] = {
         [FR_ACT_TO_TBL]      = "table",
         [FR_ACT_GOTO]        = "goto",
         [FR_ACT_NOP]         = "nop",
@@ -40,8 +34,7 @@ static const char *const fr_act_type_full_table[__FR_ACT_MAX] = {
 };
 
 assert_cc(__FR_ACT_MAX <= UINT8_MAX);
-DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(fr_act_type, int);
-DEFINE_STRING_TABLE_LOOKUP_TO_STRING(fr_act_type_full, int);
+DEFINE_STRING_TABLE_LOOKUP(fr_act_type, int);
 
 static RoutingPolicyRule* routing_policy_rule_detach_impl(RoutingPolicyRule *rule) {
         assert(rule);
@@ -519,7 +512,8 @@ static int routing_policy_rule_acquire_priority(Manager *manager, RoutingPolicyR
                                 return r;
                 }
 
-        for (priority = 32765; priority > 0; priority--)
+        /* priority must be smaller than goto target */
+        for (priority = rule->type == FR_ACT_GOTO ? rule->priority_goto - 1 : 32765; priority > 0; priority--)
                 if (!set_contains(priorities, UINT32_TO_PTR(priority)))
                         break;
 
@@ -1432,6 +1426,48 @@ int config_parse_routing_policy_rule_priority(
         return 0;
 }
 
+int config_parse_routing_policy_rule_goto(
+                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_unref_or_set_invalidp) RoutingPolicyRule *n = NULL;
+        Network *network = ASSERT_PTR(userdata);
+        uint32_t priority;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        r = routing_policy_rule_new_static(network, filename, section_line, &n);
+        if (r < 0)
+                return log_oom();
+
+        r = safe_atou32(rvalue, &priority);
+        if (r < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse %s=%s, ignoring assignment: %m", lvalue, rvalue);
+                return 0;
+        }
+        if (priority <= 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid goto target priority, ignoring assignment.");
+                return 0;
+        }
+
+        n->type = FR_ACT_GOTO;
+        n->priority_goto = priority;
+
+        TAKE_PTR(n);
+        return 0;
+}
+
 int config_parse_routing_policy_rule_table(
                 const char *unit,
                 const char *filename,
@@ -1988,6 +2024,23 @@ static int routing_policy_rule_section_verify(RoutingPolicyRule *rule) {
         if (rule->l3mdev)
                 rule->table = RT_TABLE_UNSPEC;
 
+        if (rule->type == FR_ACT_GOTO) {
+                if (rule->priority_goto <= 0)
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                               "%s: Type=goto is specified but the target priority GoTo= is unspecified. "
+                                               "Ignoring [RoutingPolicyRule] section from line %u.",
+                                               rule->section->filename,
+                                               rule->section->line);
+
+                if (rule->priority_set && rule->priority >= rule->priority_goto)
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                               "%s: goto target priority %"PRIu32" must be larger than the priority of this rule %"PRIu32". "
+                                               "Ignoring [RoutingPolicyRule] section from line %u.",
+                                               rule->section->filename,
+                                               rule->priority_goto, rule->priority,
+                                               rule->section->line);
+        }
+
         return 0;
 }
 
index 3ca5e73934a98f2bf7dc8e6b3c9eddcc28cd289b..c7a0512b44f89bc5ba1631aea344f74ac9081072 100644 (file)
@@ -54,7 +54,8 @@ typedef struct RoutingPolicyRule {
         struct fib_rule_port_range dport; /* FRA_DPORT_RANGE */
 } RoutingPolicyRule;
 
-const char* fr_act_type_full_to_string(int t) _const_;
+int fr_act_type_from_string(const char *s) _pure_;
+const char* fr_act_type_to_string(int t) _const_;
 
 RoutingPolicyRule* routing_policy_rule_ref(RoutingPolicyRule *rule);
 RoutingPolicyRule* routing_policy_rule_unref(RoutingPolicyRule *rule);
@@ -81,6 +82,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_table);
 CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_fwmark_mask);
 CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_prefix);
 CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_priority);
+CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_goto);
 CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_device);
 CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_l3mdev);
 CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_port_range);