summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2021-06-06 14:14:44 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2021-06-09 04:59:23 +0900
commit7558f9e717381eef0ddc8ddfb5a754ea4b0f3e6c (patch)
tree80e96b8a4c072f7c613b38e4eb28ce69cce4d8ec /src
parent7ff9d99e9e8b75930aa05b45eb21889eac8af014 (diff)
downloadsystemd-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.c125
-rw-r--r--src/network/networkd-can.h4
-rw-r--r--src/network/networkd-link.c36
-rw-r--r--src/network/networkd-link.h1
-rw-r--r--src/network/networkd-setlink.c37
-rw-r--r--src/network/networkd-setlink.h4
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);