]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
kernel-netlink: Add options to enable parallel Netlink queries explicitly
authorMartin Willi <martin@revosec.ch>
Wed, 16 Jul 2014 10:38:30 +0000 (12:38 +0200)
committerMartin Willi <martin@revosec.ch>
Fri, 21 Nov 2014 09:55:45 +0000 (10:55 +0100)
As under vanilla Linux the kernel can't handle parallel dump queries and returns
EBUSY, it makes not much sense to use them. Disable parallel queries by default
to basically restore original behavior, improving performance.

src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c
src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.h
src/libhydra/plugins/kernel_netlink/suites/test_socket.c

index dfd71f3bd58d562a3f90630862830e932779392b..80c8e24339a4fd512f39e18296ec932a3363c677 100644 (file)
@@ -2711,7 +2711,9 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
                fclose(f);
        }
 
-       this->socket_xfrm = netlink_socket_create(NETLINK_XFRM, xfrm_msg_names);
+       this->socket_xfrm = netlink_socket_create(NETLINK_XFRM, xfrm_msg_names,
+                               lib->settings->get_bool(lib->settings,
+                                       "%s.plugins.kernel-netlink.parallel_xfrm", FALSE, lib->ns));
        if (!this->socket_xfrm)
        {
                destroy(this);
index 3c1a3f87dd0a5d7a330a6259825477f395bd2894..b8cd3977d1410821a7d48488509af4d72677d035 100644 (file)
@@ -2499,7 +2499,9 @@ kernel_netlink_net_t *kernel_netlink_net_create()
                                .destroy = _destroy,
                        },
                },
-               .socket = netlink_socket_create(NETLINK_ROUTE, rt_msg_names),
+               .socket = netlink_socket_create(NETLINK_ROUTE, rt_msg_names,
+                       lib->settings->get_bool(lib->settings,
+                               "%s.plugins.kernel-netlink.parallel_route", FALSE, lib->ns)),
                .rt_exclude = linked_list_create(),
                .routes = hashtable_create((hashtable_hash_t)route_entry_hash,
                                                                   (hashtable_equals_t)route_entry_equals, 16),
index 2875436c6b1f765a46d415d231ff33b0fcdd15b7..ba3b17e2322f4155bb51a5182a7320598588b75d 100644 (file)
@@ -75,6 +75,11 @@ struct private_netlink_socket_t {
         * Number of times to repeat timed out queries
         */
        u_int retries;
+
+       /**
+        * Use parallel netlink queries
+        */
+       bool parallel;
 };
 
 /**
@@ -290,7 +295,8 @@ static status_t send_once(private_netlink_socket_t *this, struct nlmsghdr *in,
 
        while (!entry->complete)
        {
-               if (lib->watcher->get_state(lib->watcher) == WATCHER_RUNNING)
+               if (this->parallel &&
+                       lib->watcher->get_state(lib->watcher) == WATCHER_RUNNING)
                {
                        if (this->timeout)
                        {
@@ -450,7 +456,10 @@ METHOD(netlink_socket_t, destroy, void,
 {
        if (this->socket != -1)
        {
-               lib->watcher->remove(lib->watcher, this->socket);
+               if (this->parallel)
+               {
+                       lib->watcher->remove(lib->watcher, this->socket);
+               }
                close(this->socket);
        }
        this->entries->destroy(this->entries);
@@ -461,7 +470,8 @@ METHOD(netlink_socket_t, destroy, void,
 /**
  * Described in header.
  */
-netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names)
+netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names,
+                                                                               bool parallel)
 {
        private_netlink_socket_t *this;
        struct sockaddr_nl addr = {
@@ -483,6 +493,7 @@ netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names)
                                                        "%s.plugins.kernel-netlink.timeout", 0, lib->ns),
                .retries = lib->settings->get_int(lib->settings,
                                                        "%s.plugins.kernel-netlink.retries", 0, lib->ns),
+               .parallel = parallel,
        );
 
        if (this->socket == -1)
@@ -497,8 +508,10 @@ netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names)
                destroy(this);
                return NULL;
        }
-
-       lib->watcher->add(lib->watcher, this->socket, WATCHER_READ, watch, this);
+       if (this->parallel)
+       {
+               lib->watcher->add(lib->watcher, this->socket, WATCHER_READ, watch, this);
+       }
 
        return &this->public;
 }
index 069f746d10a70609d4486b938a5f7502866de038..66682907d9536b5ee0fbfb9bf45d38d667616bb6 100644 (file)
@@ -66,8 +66,10 @@ struct netlink_socket_t {
  *
  * @param protocol     protocol type (e.g. NETLINK_XFRM or NETLINK_ROUTE)
  * @param names                optional enum names for Netlink messages
+ * @param parallel     support parallel queries on this Netlink socket
  */
-netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names);
+netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names,
+                                                                               bool parallel);
 
 /**
  * Creates an rtattr and adds it to the given netlink message.
index c66aa2c02ca7ba80d89e8f1e0b2befc4dbfe5a76..3e8facd0abda48d06d697b9b16d4bd0d6bd5f747 100644 (file)
@@ -60,7 +60,7 @@ START_TEST(test_echo)
        netlink_add_attribute(&request.hdr, RTA_DST,
                                                  chunk_from_thing(dst), sizeof(request));
 
-       s = netlink_socket_create(NETLINK_ROUTE, NULL);
+       s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
 
        ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS);
        ck_assert_int_eq(out->nlmsg_type, RTM_NEWROUTE);
@@ -83,7 +83,7 @@ START_TEST(test_echo_dump)
                },
        };
 
-       s = netlink_socket_create(NETLINK_ROUTE, NULL);
+       s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
        msg = NLMSG_DATA(&request.hdr);
        msg->rtgen_family = AF_UNSPEC;
 
@@ -179,7 +179,7 @@ START_TEST(test_stress)
        netlink_socket_t *s;
        int i;
 
-       s = netlink_socket_create(NETLINK_ROUTE, NULL);
+       s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
        for (i = 0; i < countof(threads); i++)
        {
                threads[i] = thread_create(stress, s);
@@ -198,7 +198,7 @@ START_TEST(test_stress_dump)
        netlink_socket_t *s;
        int i;
 
-       s = netlink_socket_create(NETLINK_ROUTE, NULL);
+       s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
        for (i = 0; i < countof(threads); i++)
        {
                threads[i] = thread_create(stress_dump, s);
@@ -232,7 +232,7 @@ START_TEST(test_retransmit_success)
        lib->settings->set_int(lib->settings,
                                                        "%s.plugins.kernel-netlink.retries", 1, lib->ns);
 
-       s = netlink_socket_create(NETLINK_ROUTE, NULL);
+       s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
        msg = NLMSG_DATA(&request.hdr);
        msg->rtgen_family = AF_UNSPEC;
 
@@ -265,7 +265,7 @@ START_TEST(test_retransmit_fail)
        lib->settings->set_int(lib->settings,
                                                        "%s.plugins.kernel-netlink.retries", 3, lib->ns);
 
-       s = netlink_socket_create(NETLINK_ROUTE, NULL);
+       s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
        msg = NLMSG_DATA(&request.hdr);
        msg->rtgen_family = AF_UNSPEC;
 
@@ -284,18 +284,18 @@ Suite *socket_suite_create()
        s = suite_create("netlink socket");
 
        tc = tcase_create("echo");
-       tcase_add_test(tc, test_echo);
-       tcase_add_test(tc, test_echo_dump);
+       tcase_add_loop_test(tc, test_echo, 0, 2);
+       tcase_add_loop_test(tc, test_echo_dump, 0, 2);
        suite_add_tcase(s, tc);
 
        tc = tcase_create("stress");
-       tcase_add_test(tc, test_stress);
-       tcase_add_test(tc, test_stress_dump);
+       tcase_add_loop_test(tc, test_stress, 0, 2);
+       tcase_add_loop_test(tc, test_stress_dump, 0, 2);
        suite_add_tcase(s, tc);
 
        tc = tcase_create("retransmit");
-       tcase_add_test(tc, test_retransmit_success);
-       tcase_add_test(tc, test_retransmit_fail);
+       tcase_add_loop_test(tc, test_retransmit_success, 0, 2);
+       tcase_add_loop_test(tc, test_retransmit_fail, 0, 2);
        suite_add_tcase(s, tc);
 
        return s;