]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: use void* to correctly store SetLinkOperation in Request
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 14 Jun 2021 10:46:33 +0000 (19:46 +0900)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 15 Jun 2021 18:58:20 +0000 (20:58 +0200)
Previously, when `link_request_queue()` is called in link_request_set_link(),
`SetLinkOperation` is casted with INT_TO_PTR(), and the value is assigned to
`void *object`. However the value was read directly through the member
`SetLinkOperation set_link_operation` of the union which `object`
beloging to. Thus, read value was always 0 on big-endian systems.

Fixes configuring link issue on s390x systems.

src/network/netdev/netdev.c
src/network/networkd-queue.c
src/network/networkd-queue.h
src/network/networkd-setlink.c
src/network/networkd-setlink.h

index 89c52a00d2be2109bb8fd8c76c4692e4c1c9c632..53534d4873410876ca0009a38f960f6d42970376 100644 (file)
@@ -26,6 +26,7 @@
 #include "netlink-util.h"
 #include "networkd-manager.h"
 #include "networkd-queue.h"
+#include "networkd-setlink.h"
 #include "nlmon.h"
 #include "path-lookup.h"
 #include "siphash24.h"
@@ -550,7 +551,7 @@ static bool netdev_is_ready_to_create(NetDev *netdev, Link *link) {
         req = (Request) {
                 .link = link,
                 .type = REQUEST_TYPE_SET_LINK,
-                .set_link_operation = SET_LINK_MTU,
+                .set_link_operation_ptr = INT_TO_PTR(SET_LINK_MTU),
         };
 
         if (ordered_set_contains(link->manager->request_queue, &req))
index dfb4a2bf127dbcb4528dd68da4f9d35cdc20b13e..3480f5c8905f9071dcae67eb2b407292ed2d27f2 100644 (file)
@@ -12,6 +12,7 @@
 #include "networkd-route.h"
 #include "networkd-routing-policy-rule.h"
 #include "networkd-queue.h"
+#include "networkd-setlink.h"
 
 static void request_free_object(RequestType type, void *object) {
         switch(type) {
@@ -123,9 +124,10 @@ static void request_hash_func(const Request *req, struct siphash *state) {
         case REQUEST_TYPE_ROUTING_POLICY_RULE:
                 routing_policy_rule_hash_func(req->rule, state);
                 break;
-        case REQUEST_TYPE_SET_LINK:
-                siphash24_compress(&req->set_link_operation, sizeof(req->set_link_operation), state);
+        case REQUEST_TYPE_SET_LINK: {
+                trivial_hash_func(req->set_link_operation_ptr, state);
                 break;
+        }
         case REQUEST_TYPE_UP_DOWN:
                 break;
         default:
@@ -172,7 +174,7 @@ static int request_compare_func(const struct Request *a, const struct Request *b
         case REQUEST_TYPE_ROUTING_POLICY_RULE:
                 return routing_policy_rule_compare_func(a->rule, b->rule);
         case REQUEST_TYPE_SET_LINK:
-                return CMP(a->set_link_operation, b->set_link_operation);
+                return trivial_compare_func(a->set_link_operation_ptr, b->set_link_operation_ptr);
         case REQUEST_TYPE_UP_DOWN:
                 return 0;
         default:
index c3d7f050792a15f422ba73de833da02af35743b9..1f4b15f087dd2ae09b528203fbf6dc2b9134b92a 100644 (file)
@@ -4,7 +4,6 @@
 #include "sd-event.h"
 
 #include "networkd-link.h"
-#include "networkd-setlink.h"
 
 typedef struct Address Address;
 typedef struct AddressLabel AddressLabel;
@@ -40,8 +39,6 @@ typedef enum RequestType {
         _REQUEST_TYPE_INVALID = -EINVAL,
 } RequestType;
 
-assert_cc(sizeof(SetLinkOperation) <= sizeof(void*));
-
 typedef struct Request {
         Link *link;
         RequestType type;
@@ -56,7 +53,7 @@ typedef struct Request {
                 NextHop *nexthop;
                 Route *route;
                 RoutingPolicyRule *rule;
-                SetLinkOperation set_link_operation;
+                void *set_link_operation_ptr;
                 NetDev *netdev;
                 void *object;
         };
index 126a14b8bc92d6efcdfe580d8061d274ecb69d86..a316a6c59b5aafe749d1d87d3a2b16168121c81f 100644 (file)
@@ -10,8 +10,8 @@
 #include "networkd-link.h"
 #include "networkd-manager.h"
 #include "networkd-queue.h"
+#include "networkd-setlink.h"
 #include "string-table.h"
-#include "sysctl-util.h"
 
 static const char *const set_link_operation_table[_SET_LINK_OPERATION_MAX] = {
         [SET_LINK_ADDRESS_GENERATION_MODE] = "IPv6LL address generation mode",
@@ -491,7 +491,7 @@ static bool link_is_ready_to_call_set_link(Request *req) {
         assert(req);
 
         link = req->link;
-        op = req->set_link_operation;
+        op = PTR_TO_INT(req->set_link_operation_ptr);
 
         if (!IN_SET(link->state, LINK_STATE_INITIALIZED, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
                 return false;
@@ -572,23 +572,27 @@ static bool link_is_ready_to_call_set_link(Request *req) {
 }
 
 int request_process_set_link(Request *req) {
+        SetLinkOperation op;
         int r;
 
         assert(req);
         assert(req->link);
         assert(req->type == REQUEST_TYPE_SET_LINK);
-        assert(req->set_link_operation >= 0 && req->set_link_operation < _SET_LINK_OPERATION_MAX);
         assert(req->netlink_handler);
 
+        op = PTR_TO_INT(req->set_link_operation_ptr);
+
+        assert(op >= 0 && op < _SET_LINK_OPERATION_MAX);
+
         if (!link_is_ready_to_call_set_link(req))
                 return 0;
 
-        r = link_configure(req->link, req->set_link_operation, req->userdata, req->netlink_handler);
+        r = link_configure(req->link, op, req->userdata, req->netlink_handler);
         if (r < 0)
                 return log_link_error_errno(req->link, r, "Failed to set %s: %m",
-                                            set_link_operation_to_string(req->set_link_operation));
+                                            set_link_operation_to_string(op));
 
-        if (req->set_link_operation == SET_LINK_FLAGS)
+        if (op == SET_LINK_FLAGS)
                 req->link->set_flags_messages++;
 
         return 1;
index 87aa26e46f6d5bbbd57b1e46e8c374820beb61a7..d3e9f2b9d7b4027804f140ee8680b1eae3fc3ad8 100644 (file)
@@ -21,6 +21,10 @@ typedef enum SetLinkOperation {
         _SET_LINK_OPERATION_INVALID = -EINVAL,
 } SetLinkOperation;
 
+/* SetLinkOperation is casted to int, then stored in void* with INT_TO_PTR(). */
+assert_cc(sizeof(SetLinkOperation) <= sizeof(void*));
+assert_cc(sizeof(SetLinkOperation) <= sizeof(int));
+
 int link_request_to_set_addrgen_mode(Link *link);
 int link_request_to_set_bond(Link *link);
 int link_request_to_set_bridge(Link *link);