diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-06-06 14:14:44 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-06-09 04:59:23 +0900 |
commit | 7558f9e717381eef0ddc8ddfb5a754ea4b0f3e6c (patch) | |
tree | 80e96b8a4c072f7c613b38e4eb28ce69cce4d8ec /src | |
parent | 7ff9d99e9e8b75930aa05b45eb21889eac8af014 (diff) | |
download | systemd-7558f9e717381eef0ddc8ddfb5a754ea4b0f3e6c.tar.gz |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/network/networkd-can.c | 125 | ||||
-rw-r--r-- | src/network/networkd-can.h | 4 | ||||
-rw-r--r-- | src/network/networkd-link.c | 36 | ||||
-rw-r--r-- | src/network/networkd-link.h | 1 | ||||
-rw-r--r-- | src/network/networkd-setlink.c | 37 | ||||
-rw-r--r-- | src/network/networkd-setlink.h | 4 |
6 files changed, 85 insertions, 122 deletions
diff --git a/src/network/networkd-can.c b/src/network/networkd-can.c index c2644a1b8e..1fa37a0584 100644 --- a/src/network/networkd-can.c +++ b/src/network/networkd-can.c @@ -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; } diff --git a/src/network/networkd-can.h b/src/network/networkd-can.h index 7a2705bf9a..781494ed3c 100644 --- a/src/network/networkd-can.h +++ b/src/network/networkd-can.h @@ -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); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 8f70d5da3a..56eacdd0a1 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -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); } diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index a3cc829ca6..aa30019a13 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -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; diff --git a/src/network/networkd-setlink.c b/src/network/networkd-setlink.c index e9269d36ef..a66033b2a7 100644 --- a/src/network/networkd-setlink.c +++ b/src/network/networkd-setlink.c @@ -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); diff --git a/src/network/networkd-setlink.h b/src/network/networkd-setlink.h index 463a2d114f..eb2633618b 100644 --- a/src/network/networkd-setlink.h +++ b/src/network/networkd-setlink.h @@ -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); |