]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: use request queue to configure CAN interfaces
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 6 Jun 2021 05:14:44 +0000 (14:14 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 8 Jun 2021 19:59:23 +0000 (04:59 +0900)
This also makes SR-IOV configurations are ignored for CAN interfaces,
as CAN interfaces seem not to support SR-IOV features.

src/network/networkd-can.c
src/network/networkd-can.h
src/network/networkd-link.c
src/network/networkd-link.h
src/network/networkd-setlink.c
src/network/networkd-setlink.h

index c2644a1b8e13488cfabb06ad809cdd9ddaf0753a..1fa37a058425c202583a632ed8a64546dbd55748 100644 (file)
@@ -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;
 }
index 7a2705bf9a09fc0374c133b3b8fcde20b819c388..781494ed3c9a925db147e90e89a6c5a81578d490 100644 (file)
@@ -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);
index 8f70d5da3af5328d6705f67259f9121a6c037fec..56eacdd0a19cf8d8fe508aaad0458323092df935 100644 (file)
@@ -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);
         }
index a3cc829ca6e4bd410b9343618179fa2272be5936..aa30019a13da342f472c3d2ea3991fdaee6b4d50 100644 (file)
@@ -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;
index e9269d36ef602acc644446a2fe32aac7a9c522de..a66033b2a7325ca45d455f8bf472a70fa34a3ba7 100644 (file)
@@ -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);
index 463a2d114f5ad994851777b7cdf14b9c9c098141..eb2633618bc12508dd7f6bfe4e5ba39894b3b2a1 100644 (file)
@@ -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);