diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index 43f69851c5..6ad22bd5c8 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -746,6 +746,11 @@ static const RoutingPolicyRule kernel_rules[] = { static bool routing_policy_rule_is_created_by_kernel(const RoutingPolicyRule *rule) { assert(rule); + if (rule->l3mdev > 0) + /* Currently, [RoutingPolicyRule] does not explicitly set FRA_L3MDEV. So, if the flag + * is set, it is safe to treat the rule as created by kernel. */ + return true; + for (size_t i = 0; i < ELEMENTSOF(kernel_rules); i++) if (routing_policy_rule_equal(rule, &kernel_rules[i])) return true; @@ -900,6 +905,12 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man return 0; } + r = sd_netlink_message_read_u8(message, FRA_L3MDEV, &tmp->l3mdev); + if (r < 0 && r != -ENODATA) { + log_warning_errno(r, "rtnl: could not get FRA_L3MDEV attribute, ignoring: %m"); + return 0; + } + r = sd_netlink_message_read(message, FRA_SPORT_RANGE, sizeof(tmp->sport), &tmp->sport); if (r < 0 && r != -ENODATA) { log_warning_errno(r, "rtnl: could not get FRA_SPORT_RANGE attribute, ignoring: %m"); @@ -1544,6 +1555,12 @@ static int routing_policy_rule_section_verify(RoutingPolicyRule *rule) { if (rule->family == AF_UNSPEC && rule->address_family == ADDRESS_FAMILY_NO) rule->family = AF_INET; + /* Currently, [RoutingPolicyRule] does not have a setting to set FRA_L3MDEV flag. Please also + * update routing_policy_rule_is_created_by_kernel() when a new setting which sets the flag is + * added in the future. */ + if (rule->l3mdev > 0) + assert_not_reached("FRA_L3MDEV flag should not be configured."); + return 0; } diff --git a/src/network/networkd-routing-policy-rule.h b/src/network/networkd-routing-policy-rule.h index 3786eee34b..ded312b73e 100644 --- a/src/network/networkd-routing-policy-rule.h +++ b/src/network/networkd-routing-policy-rule.h @@ -28,6 +28,7 @@ typedef struct RoutingPolicyRule { uint8_t protocol; /* FRA_PROTOCOL */ uint8_t to_prefixlen; uint8_t from_prefixlen; + uint8_t l3mdev; /* FRA_L3MDEV */ uint32_t table; uint32_t fwmark;