mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
network: use void* to correctly store SetLinkOperation in Request
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.
This commit is contained in:
parent
b428efa54b
commit
9b682672e4
@ -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))
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user