network: use request queue to configure CAN interfaces
This also makes SR-IOV configurations are ignored for CAN interfaces, as CAN interfaces seem not to support SR-IOV features.
This commit is contained in:
+26
-99
@@ -3,10 +3,9 @@
|
||||
#include <net/if.h>
|
||||
#include <linux/can/netlink.h>
|
||||
|
||||
#include "netlink-util.h"
|
||||
#include "networkd-can.h"
|
||||
#include "networkd-link.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-network.h"
|
||||
#include "networkd-setlink.h"
|
||||
#include "parse-util.h"
|
||||
#include "string-util.h"
|
||||
@@ -53,62 +52,25 @@ int config_parse_can_bitrate(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int link_set_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "Failed to configure CAN link");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
}
|
||||
|
||||
log_link_debug(link, "Link set");
|
||||
|
||||
r = link_request_to_activate(link);
|
||||
if (r < 0) {
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
}
|
||||
|
||||
link->can_configured = true;
|
||||
link_check_ready(link);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int link_set_can(Link *link) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||
int can_set_netlink_message(Link *link, sd_netlink_message *m) {
|
||||
struct can_ctrlmode cm = {};
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
assert(link->manager);
|
||||
assert(link->manager->rtnl);
|
||||
|
||||
log_link_debug(link, "Configuring CAN link.");
|
||||
|
||||
r = sd_rtnl_message_new_link(link->manager->rtnl, &m, RTM_NEWLINK, link->ifindex);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to allocate netlink message: %m");
|
||||
assert(m);
|
||||
|
||||
r = sd_netlink_message_set_flags(m, NLM_F_REQUEST | NLM_F_ACK);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set netlink flags: %m");
|
||||
return log_link_debug_errno(link, r, "Could not set netlink flags: %m");
|
||||
|
||||
r = sd_netlink_message_open_container(m, IFLA_LINKINFO);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to open netlink container: %m");
|
||||
return log_link_debug_errno(link, r, "Failed to open IFLA_LINKINFO container: %m");
|
||||
|
||||
r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, link->kind);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m");
|
||||
return log_link_debug_errno(link, r, "Could not open IFLA_INFO_DATA container: %m");
|
||||
|
||||
if (link->network->can_bitrate > 0 || link->network->can_sample_point > 0) {
|
||||
struct can_bittiming bt = {
|
||||
@@ -124,7 +86,7 @@ static int link_set_can(Link *link) {
|
||||
|
||||
r = sd_netlink_message_append_data(m, IFLA_CAN_BITTIMING, &bt, sizeof(bt));
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append IFLA_CAN_BITTIMING attribute: %m");
|
||||
return log_link_debug_errno(link, r, "Could not append IFLA_CAN_BITTIMING attribute: %m");
|
||||
}
|
||||
|
||||
if (link->network->can_data_bitrate > 0 || link->network->can_data_sample_point > 0) {
|
||||
@@ -141,19 +103,7 @@ static int link_set_can(Link *link) {
|
||||
|
||||
r = sd_netlink_message_append_data(m, IFLA_CAN_DATA_BITTIMING, &bt, sizeof(bt));
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append IFLA_CAN_DATA_BITTIMING attribute: %m");
|
||||
}
|
||||
|
||||
if (link->network->can_fd_mode >= 0) {
|
||||
cm.mask |= CAN_CTRLMODE_FD;
|
||||
SET_FLAG(cm.flags, CAN_CTRLMODE_FD, link->network->can_fd_mode);
|
||||
log_link_debug(link, "Setting FD mode to '%s'.", yes_no(link->network->can_fd_mode));
|
||||
}
|
||||
|
||||
if (link->network->can_non_iso >= 0) {
|
||||
cm.mask |= CAN_CTRLMODE_FD_NON_ISO;
|
||||
SET_FLAG(cm.flags, CAN_CTRLMODE_FD_NON_ISO, link->network->can_non_iso);
|
||||
log_link_debug(link, "Setting FD non-ISO mode to '%s'.", yes_no(link->network->can_non_iso));
|
||||
return log_link_debug_errno(link, r, "Could not append IFLA_CAN_DATA_BITTIMING attribute: %m");
|
||||
}
|
||||
|
||||
if (link->network->can_restart_us > 0) {
|
||||
@@ -168,13 +118,25 @@ static int link_set_can(Link *link) {
|
||||
format_timespan(time_string, FORMAT_TIMESPAN_MAX, restart_ms * 1000, MSEC_PER_SEC);
|
||||
|
||||
if (restart_ms > UINT32_MAX)
|
||||
return log_link_error_errno(link, SYNTHETIC_ERRNO(ERANGE), "restart timeout (%s) too big.", time_string);
|
||||
return log_link_debug_errno(link, SYNTHETIC_ERRNO(ERANGE), "restart timeout (%s) too big.", time_string);
|
||||
|
||||
log_link_debug(link, "Setting restart = %s", time_string);
|
||||
|
||||
r = sd_netlink_message_append_u32(m, IFLA_CAN_RESTART_MS, restart_ms);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append IFLA_CAN_RESTART_MS attribute: %m");
|
||||
return log_link_debug_errno(link, r, "Could not append IFLA_CAN_RESTART_MS attribute: %m");
|
||||
}
|
||||
|
||||
if (link->network->can_fd_mode >= 0) {
|
||||
cm.mask |= CAN_CTRLMODE_FD;
|
||||
SET_FLAG(cm.flags, CAN_CTRLMODE_FD, link->network->can_fd_mode);
|
||||
log_link_debug(link, "Setting FD mode to '%s'.", yes_no(link->network->can_fd_mode));
|
||||
}
|
||||
|
||||
if (link->network->can_non_iso >= 0) {
|
||||
cm.mask |= CAN_CTRLMODE_FD_NON_ISO;
|
||||
SET_FLAG(cm.flags, CAN_CTRLMODE_FD_NON_ISO, link->network->can_non_iso);
|
||||
log_link_debug(link, "Setting FD non-ISO mode to '%s'.", yes_no(link->network->can_non_iso));
|
||||
}
|
||||
|
||||
if (link->network->can_triple_sampling >= 0) {
|
||||
@@ -198,60 +160,25 @@ static int link_set_can(Link *link) {
|
||||
if (cm.mask != 0) {
|
||||
r = sd_netlink_message_append_data(m, IFLA_CAN_CTRLMODE, &cm, sizeof(cm));
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append IFLA_CAN_CTRLMODE attribute: %m");
|
||||
return log_link_debug_errno(link, r, "Could not append IFLA_CAN_CTRLMODE attribute: %m");
|
||||
}
|
||||
|
||||
if (link->network->can_termination >= 0) {
|
||||
|
||||
log_link_debug(link, "Setting can-termination to '%s'.", yes_no(link->network->can_termination));
|
||||
|
||||
r = sd_netlink_message_append_u16(m, IFLA_CAN_TERMINATION,
|
||||
link->network->can_termination ? CAN_TERMINATION_OHM_VALUE : 0);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append IFLA_CAN_TERMINATION attribute: %m");
|
||||
|
||||
return log_link_debug_errno(link, r, "Could not append IFLA_CAN_TERMINATION attribute: %m");
|
||||
}
|
||||
|
||||
r = sd_netlink_message_close_container(m);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to close netlink container: %m");
|
||||
return log_link_debug_errno(link, r, "Failed to close IFLA_INFO_DATA container: %m");
|
||||
|
||||
r = sd_netlink_message_close_container(m);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to close netlink container: %m");
|
||||
|
||||
r = netlink_call_async(link->manager->rtnl, NULL, m, link_set_handler,
|
||||
link_netlink_destroy_callback, link);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||
|
||||
link_ref(link);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int link_configure_can(Link *link) {
|
||||
int r;
|
||||
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
|
||||
if (streq_ptr(link->kind, "can")) {
|
||||
/* The CAN interface must be down to configure bitrate, etc... */
|
||||
if (link->flags & IFF_UP) {
|
||||
r = link_down(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return link_set_can(link);
|
||||
}
|
||||
|
||||
r = link_request_to_activate(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
link->can_configured = true;
|
||||
link_check_ready(link);
|
||||
return log_link_debug_errno(link, r, "Failed to close IFLA_LINKINFO container: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "sd-netlink.h"
|
||||
|
||||
#include "conf-parser.h"
|
||||
|
||||
typedef struct Link Link;
|
||||
|
||||
int link_configure_can(Link *link);
|
||||
int can_set_netlink_message(Link *link, sd_netlink_message *m);
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_can_bitrate);
|
||||
|
||||
+17
-19
@@ -411,14 +411,8 @@ void link_check_ready(Link *link) {
|
||||
if (!link->network)
|
||||
return (void) log_link_debug(link, "%s(): link is unmanaged.", __func__);
|
||||
|
||||
if (link->iftype == ARPHRD_CAN) {
|
||||
/* let's shortcut things for CAN which doesn't need most of checks below. */
|
||||
if (!link->can_configured)
|
||||
return (void) log_link_debug(link, "%s(): CAN device is not configured.", __func__);
|
||||
|
||||
link_set_state(link, LINK_STATE_CONFIGURED);
|
||||
return;
|
||||
}
|
||||
if (!link->tc_configured)
|
||||
return (void) log_link_debug(link, "%s(): traffic controls are not configured.", __func__);
|
||||
|
||||
if (link->set_link_messages > 0)
|
||||
return (void) log_link_debug(link, "%s(): link layer is configuring.", __func__);
|
||||
@@ -426,6 +420,12 @@ void link_check_ready(Link *link) {
|
||||
if (!link->activated)
|
||||
return (void) log_link_debug(link, "%s(): link is not activated.", __func__);
|
||||
|
||||
if (link->iftype == ARPHRD_CAN) {
|
||||
/* let's shortcut things for CAN which doesn't need most of checks below. */
|
||||
link_set_state(link, LINK_STATE_CONFIGURED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!link->static_addresses_configured)
|
||||
return (void) log_link_debug(link, "%s(): static addresses are not configured.", __func__);
|
||||
|
||||
@@ -461,9 +461,6 @@ void link_check_ready(Link *link) {
|
||||
if (!link->static_routing_policy_rules_configured)
|
||||
return (void) log_link_debug(link, "%s(): static routing policy rules are not configured.", __func__);
|
||||
|
||||
if (!link->tc_configured)
|
||||
return (void) log_link_debug(link, "%s(): traffic controls are not configured.", __func__);
|
||||
|
||||
if (!link->sr_iov_configured)
|
||||
return (void) log_link_debug(link, "%s(): SR-IOV is not configured.", __func__);
|
||||
|
||||
@@ -1028,14 +1025,19 @@ static int link_configure(Link *link) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (link->iftype == ARPHRD_CAN) {
|
||||
/* let's shortcut things for CAN which doesn't need most of what's done below. */
|
||||
r = link_request_to_set_can(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return link_request_to_activate(link);
|
||||
}
|
||||
|
||||
r = link_configure_sr_iov(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (link->iftype == ARPHRD_CAN)
|
||||
/* let's shortcut things for CAN which doesn't need most of what's done below. */
|
||||
return link_configure_can(link);
|
||||
|
||||
r = link_set_sysctl(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -1588,10 +1590,6 @@ static int link_admin_state_down(Link *link) {
|
||||
return 0;
|
||||
|
||||
if (link->network->activation_policy == ACTIVATION_POLICY_ALWAYS_UP) {
|
||||
if (streq_ptr(link->kind, "can") && !link->can_configured)
|
||||
/* CAN device needs to be down on configure. */
|
||||
return 0;
|
||||
|
||||
log_link_info(link, "ActivationPolicy is \"always-on\", forcing link up");
|
||||
return link_up(link);
|
||||
}
|
||||
|
||||
@@ -136,7 +136,6 @@ typedef struct Link {
|
||||
bool static_routing_policy_rules_configured:1;
|
||||
bool tc_configured:1;
|
||||
bool sr_iov_configured:1;
|
||||
bool can_configured:1;
|
||||
bool activated:1;
|
||||
bool master_set:1;
|
||||
bool stacked_netdevs_created:1;
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_arp.h>
|
||||
|
||||
#include "missing_network.h"
|
||||
#include "netlink-util.h"
|
||||
#include "networkd-can.h"
|
||||
#include "networkd-link.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-queue.h"
|
||||
@@ -16,6 +18,7 @@ static const char *const set_link_operation_table[_SET_LINK_OPERATION_MAX] = {
|
||||
[SET_LINK_BOND] = "bond configurations",
|
||||
[SET_LINK_BRIDGE] = "bridge configurations",
|
||||
[SET_LINK_BRIDGE_VLAN] = "bridge VLAN configurations",
|
||||
[SET_LINK_CAN] = "CAN interface configurations",
|
||||
[SET_LINK_FLAGS] = "link flags",
|
||||
[SET_LINK_GROUP] = "interface group",
|
||||
[SET_LINK_MAC] = "MAC address",
|
||||
@@ -111,6 +114,10 @@ static int link_set_bridge_vlan_handler(sd_netlink *rtnl, sd_netlink_message *m,
|
||||
return set_link_handler_internal(rtnl, m, link, SET_LINK_BRIDGE_VLAN, true, NULL);
|
||||
}
|
||||
|
||||
static int link_set_can_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
return set_link_handler_internal(rtnl, m, link, SET_LINK_CAN, false, NULL);
|
||||
}
|
||||
|
||||
static int link_set_flags_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
return set_link_handler_internal(rtnl, m, link, SET_LINK_FLAGS, true, get_link_default_handler);
|
||||
}
|
||||
@@ -161,7 +168,7 @@ static int link_configure(
|
||||
|
||||
log_link_debug(link, "Setting %s", set_link_operation_to_string(op));
|
||||
|
||||
if (op == SET_LINK_BOND) {
|
||||
if (IN_SET(op, SET_LINK_BOND, SET_LINK_CAN)) {
|
||||
r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_NEWLINK, link->master_ifindex);
|
||||
if (r < 0)
|
||||
return log_link_debug_errno(link, r, "Could not allocate RTM_NEWLINK message: %m");
|
||||
@@ -349,6 +356,11 @@ static int link_configure(
|
||||
return log_link_debug_errno(link, r, "Could not close IFLA_AF_SPEC container: %m");
|
||||
|
||||
break;
|
||||
case SET_LINK_CAN:
|
||||
r = can_set_netlink_message(link, req);
|
||||
if (r < 0)
|
||||
return r;
|
||||
break;
|
||||
case SET_LINK_FLAGS: {
|
||||
unsigned ifi_change = 0, ifi_flags = 0;
|
||||
|
||||
@@ -442,6 +454,16 @@ static bool link_is_ready_to_call_set_link(Request *req) {
|
||||
if (!link->master_set)
|
||||
return false;
|
||||
break;
|
||||
case SET_LINK_CAN:
|
||||
if (FLAGS_SET(link->flags, IFF_UP)) {
|
||||
/* The CAN interface must be down to configure bitrate, etc... */
|
||||
r = link_down(link);
|
||||
if (r < 0) {
|
||||
link_enter_failed(link);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SET_LINK_MASTER: {
|
||||
uint32_t m = 0;
|
||||
|
||||
@@ -599,6 +621,19 @@ int link_request_to_set_bridge_vlan(Link *link) {
|
||||
return link_request_set_link(link, SET_LINK_BRIDGE_VLAN, link_set_bridge_vlan_handler, NULL);
|
||||
}
|
||||
|
||||
int link_request_to_set_can(Link *link) {
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
|
||||
if (link->iftype != ARPHRD_CAN)
|
||||
return 0;
|
||||
|
||||
if (!streq_ptr(link->kind, "can"))
|
||||
return 0;
|
||||
|
||||
return link_request_set_link(link, SET_LINK_CAN, link_set_can_handler, NULL);
|
||||
}
|
||||
|
||||
int link_request_to_set_flags(Link *link) {
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
|
||||
@@ -10,7 +10,8 @@ typedef enum SetLinkOperation {
|
||||
SET_LINK_ADDRESS_GENERATION_MODE, /* Setting IPv6LL address generation mode. */
|
||||
SET_LINK_BOND, /* Setting bond configs. */
|
||||
SET_LINK_BRIDGE, /* Setting bridge configs. */
|
||||
SET_LINK_BRIDGE_VLAN, /* Setting bridge vlan configs. */
|
||||
SET_LINK_BRIDGE_VLAN, /* Setting bridge VLAN configs. */
|
||||
SET_LINK_CAN, /* Setting CAN interface configs. */
|
||||
SET_LINK_FLAGS, /* Setting IFF_NOARP or friends. */
|
||||
SET_LINK_GROUP, /* Setting interface group. */
|
||||
SET_LINK_MAC, /* Setting MAC address. */
|
||||
@@ -24,6 +25,7 @@ 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);
|
||||
int link_request_to_set_bridge_vlan(Link *link);
|
||||
int link_request_to_set_can(Link *link);
|
||||
int link_request_to_set_flags(Link *link);
|
||||
int link_request_to_set_group(Link *link);
|
||||
int link_request_to_set_mac(Link *link);
|
||||
|
||||
Reference in New Issue
Block a user