network/routing-policy-rule: skip requesting when rule is already requested
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 19 Aug 2024 18:56:33 +0000 (03:56 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 20 Aug 2024 12:00:05 +0000 (21:00 +0900)
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.

src/network/networkd-queue.c
src/network/networkd-routing-policy-rule.c

index 98c629f161dc6bf556f648d18cfd889cef53d29d..73dcf67a382d259dbe79f7bf238dc8c81423a8a1 100644 (file)
@@ -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;
index 2c3e56b390fc26fe98770080a12c76ada3aeb30c..95261fc25899650d5d4774bc148abfa0a3b526c5 100644 (file)
@@ -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;