From: Yu Watanabe Date: Mon, 19 Aug 2024 18:56:33 +0000 (+0900) Subject: network/routing-policy-rule: skip requesting when rule is already requested X-Git-Tag: v257-rc1~669^2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4f8b153d903fd4a6e8d7d3e49113582d70d1525a;p=thirdparty%2Fsystemd.git network/routing-policy-rule: skip requesting when rule is already requested If it is already requested, the new request will be anyway silently refused by link_queue_request_safe(), which returns 0 in such case. Let's return earlier. There should be no functional change, just refactoring. --- diff --git a/src/network/networkd-queue.c b/src/network/networkd-queue.c index 98c629f161d..73dcf67a382 100644 --- a/src/network/networkd-queue.c +++ b/src/network/networkd-queue.c @@ -58,7 +58,11 @@ static void request_hash_func(const Request *req, struct siphash *state) { siphash24_compress_typesafe(req->type, state); - if (!IN_SET(req->type, REQUEST_TYPE_NEXTHOP, REQUEST_TYPE_ROUTE)) { + if (!IN_SET(req->type, + REQUEST_TYPE_NEXTHOP, + REQUEST_TYPE_ROUTE, + REQUEST_TYPE_ROUTING_POLICY_RULE)) { + siphash24_compress_boolean(req->link, state); if (req->link) siphash24_compress_typesafe(req->link->ifindex, state); @@ -81,7 +85,11 @@ static int request_compare_func(const struct Request *a, const struct Request *b if (r != 0) return r; - if (!IN_SET(a->type, REQUEST_TYPE_NEXTHOP, REQUEST_TYPE_ROUTE)) { + if (!IN_SET(a->type, + REQUEST_TYPE_NEXTHOP, + REQUEST_TYPE_ROUTE, + REQUEST_TYPE_ROUTING_POLICY_RULE)) { + r = CMP(!!a->link, !!b->link); if (r != 0) return r; diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index 2c3e56b390f..95261fc2589 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -378,6 +378,47 @@ static int routing_policy_rule_get(Manager *m, const RoutingPolicyRule *in, int return -ENOENT; } +static int routing_policy_rule_get_request(Manager *m, const RoutingPolicyRule *in, int family, Request **ret) { + Request *req; + + assert(m); + assert(in); + assert(in->family == AF_UNSPEC || in->family == family); + assert(IN_SET(family, AF_INET, AF_INET6)); + + if (in->priority_set && in->family != AF_UNSPEC) { + req = ordered_set_get( + m->request_queue, + &(Request) { + .type = REQUEST_TYPE_ROUTING_POLICY_RULE, + .userdata = (void*) in, + .hash_func = (hash_func_t) routing_policy_rule_hash_func, + .compare_func = (compare_func_t) routing_policy_rule_compare_func, + }); + if (!req) + return -ENOENT; + + if (ret) + *ret = req; + return 0; + } + + ORDERED_SET_FOREACH(req, m->request_queue) { + + if (req->type != REQUEST_TYPE_ROUTING_POLICY_RULE) + continue; + + RoutingPolicyRule *rule = ASSERT_PTR(req->userdata); + if (routing_policy_rule_equal(in, rule, family, rule->priority)) { + if (ret) + *ret = req; + return 0; + } + } + + return -ENOENT; +} + static int routing_policy_rule_attach(Manager *m, RoutingPolicyRule *rule) { int r; @@ -801,6 +842,9 @@ static int link_request_routing_policy_rule(Link *link, const RoutingPolicyRule assert(rule->family == AF_UNSPEC || rule->family == family); assert(IN_SET(family, AF_INET, AF_INET6)); + if (routing_policy_rule_get_request(link->manager, rule, family, NULL) >= 0) + return 0; /* already requested, skipping. */ + if (routing_policy_rule_get(link->manager, rule, family, &existing) < 0) { _cleanup_(routing_policy_rule_unrefp) RoutingPolicyRule *tmp = NULL;