]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd: add support to configure virtual CAN device (#4139)
authorSusant Sahani <ssahani@users.noreply.github.com>
Wed, 14 Sep 2016 16:15:16 +0000 (21:45 +0530)
committerMartin Pitt <martin.pitt@ubuntu.com>
Wed, 14 Sep 2016 16:15:16 +0000 (18:15 +0200)
1. add support for kind vcan
2. fixup indention netlink-types.c, networkd-netdev.c

Makefile.am
man/systemd.netdev.xml
src/libsystemd/sd-netlink/netlink-types.c
src/libsystemd/sd-netlink/netlink-types.h
src/network/networkd-link.c
src/network/networkd-netdev-vcan.c [new file with mode: 0644]
src/network/networkd-netdev-vcan.h [new file with mode: 0644]
src/network/networkd-netdev.c
src/network/networkd-netdev.h
src/network/networkd-network.c
src/network/networkd.h

index 3a617560e01d183ef7ba9af2ba5a94489d689996..946af196f31b65865c5c5b6a7f6b19cae0b277a2 100644 (file)
@@ -5650,6 +5650,8 @@ libnetworkd_core_la_SOURCES = \
        src/network/networkd-netdev-bond.c \
        src/network/networkd-netdev-bridge.h \
        src/network/networkd-netdev-bridge.c \
+       src/network/networkd-netdev-vcan.h \
+       src/network/networkd-netdev-vcan.c \
        src/network/networkd-link-bus.c \
        src/network/networkd-ipv4ll.c \
        src/network/networkd-dhcp4.c \
index 1f9f071b94a36225d351be0860aa29adb75b04cd..78f0e25a6f10ddd601a52232145a54d41c7dcbb7 100644 (file)
           <entry>A virtual extensible LAN (vxlan), for connecting Cloud computing deployments.</entry></row>
 
           <row><entry><varname>vrf</varname></entry>
-            <entry>A Virtual Routing and Forwarding (<ulink url="https://www.kernel.org/doc/Documentation/networking/vrf.txt">VRF</ulink>) interface to create separate routing and forwarding domains.</entry></row>
+          <entry>A Virtual Routing and Forwarding (<ulink url="https://www.kernel.org/doc/Documentation/networking/vrf.txt">VRF</ulink>) interface to create separate routing and forwarding domains.</entry></row>
+
+          <row><entry><varname>vcan</varname></entry>
+          <entry>The virtual CAN driver (vcan). Similar to the network loopback devices,
+          vcan offers a virtual local CAN interface.</entry></row>
 
         </tbody>
       </tgroup>
index 566a050432e331dab3e8efbf3f4753fd95cd065c..1c10dd55a75589d02fcd1ed955244b5cbc6b7eb5 100644 (file)
@@ -21,6 +21,7 @@
 #include <sys/socket.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
+#include <linux/can/netlink.h>
 #include <linux/in6.h>
 #include <linux/veth.h>
 #include <linux/if_bridge.h>
@@ -303,49 +304,48 @@ static const char* const nl_union_link_info_data_table[] = {
         [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = "vti6",
         [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = "ip6tnl",
         [NL_UNION_LINK_INFO_DATA_VRF] = "vrf",
+        [NL_UNION_LINK_INFO_DATA_VCAN] = "vcan",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData);
 
 static const NLTypeSystem rtnl_link_info_data_type_systems[] = {
-        [NL_UNION_LINK_INFO_DATA_BOND] =        { .count = ELEMENTSOF(rtnl_link_info_data_bond_types),
-                                                  .types = rtnl_link_info_data_bond_types },
-        [NL_UNION_LINK_INFO_DATA_BRIDGE] =      { .count = ELEMENTSOF(rtnl_link_info_data_bridge_types),
-                                                  .types = rtnl_link_info_data_bridge_types },
-        [NL_UNION_LINK_INFO_DATA_VLAN] =        { .count = ELEMENTSOF(rtnl_link_info_data_vlan_types),
-                                                  .types = rtnl_link_info_data_vlan_types },
-        [NL_UNION_LINK_INFO_DATA_VETH] =        { .count = ELEMENTSOF(rtnl_link_info_data_veth_types),
-                                                  .types = rtnl_link_info_data_veth_types },
-        [NL_UNION_LINK_INFO_DATA_MACVLAN] =     { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types),
-                                                  .types = rtnl_link_info_data_macvlan_types },
-        [NL_UNION_LINK_INFO_DATA_MACVTAP] =     { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types),
-                                                  .types = rtnl_link_info_data_macvlan_types },
-        [NL_UNION_LINK_INFO_DATA_IPVLAN] =      { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types),
-                                                  .types = rtnl_link_info_data_ipvlan_types },
-        [NL_UNION_LINK_INFO_DATA_VXLAN] =       { .count = ELEMENTSOF(rtnl_link_info_data_vxlan_types),
-                                                  .types = rtnl_link_info_data_vxlan_types },
-        [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types),
-                                                  .types = rtnl_link_info_data_iptun_types },
-        [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
-                                                    .types = rtnl_link_info_data_ipgre_types },
+        [NL_UNION_LINK_INFO_DATA_BOND] =             { .count = ELEMENTSOF(rtnl_link_info_data_bond_types),
+                                                       .types = rtnl_link_info_data_bond_types },
+        [NL_UNION_LINK_INFO_DATA_BRIDGE] =           { .count = ELEMENTSOF(rtnl_link_info_data_bridge_types),
+                                                       .types = rtnl_link_info_data_bridge_types },
+        [NL_UNION_LINK_INFO_DATA_VLAN] =             { .count = ELEMENTSOF(rtnl_link_info_data_vlan_types),
+                                                       .types = rtnl_link_info_data_vlan_types },
+        [NL_UNION_LINK_INFO_DATA_VETH] =             { .count = ELEMENTSOF(rtnl_link_info_data_veth_types),
+                                                       .types = rtnl_link_info_data_veth_types },
+        [NL_UNION_LINK_INFO_DATA_MACVLAN] =          { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types),
+                                                       .types = rtnl_link_info_data_macvlan_types },
+        [NL_UNION_LINK_INFO_DATA_MACVTAP] =          { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types),
+                                                       .types = rtnl_link_info_data_macvlan_types },
+        [NL_UNION_LINK_INFO_DATA_IPVLAN] =           { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types),
+                                                       .types = rtnl_link_info_data_ipvlan_types },
+        [NL_UNION_LINK_INFO_DATA_VXLAN] =            { .count = ELEMENTSOF(rtnl_link_info_data_vxlan_types),
+                                                       .types = rtnl_link_info_data_vxlan_types },
+        [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] =      { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types),
+                                                       .types = rtnl_link_info_data_iptun_types },
+        [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] =     { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
+                                                       .types = rtnl_link_info_data_ipgre_types },
         [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
-                                                    .types = rtnl_link_info_data_ipgre_types },
-        [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
-                                                    .types = rtnl_link_info_data_ipgre_types },
-        [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
-                                                    .types = rtnl_link_info_data_ipgre_types },
-        [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types),
-                                                  .types = rtnl_link_info_data_iptun_types },
-        [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types),
-                                                  .types = rtnl_link_info_data_ipvti_types },
-        [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types),
-                                                  .types = rtnl_link_info_data_ipvti_types },
-        [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] =  { .count = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types),
-                                                     .types = rtnl_link_info_data_ip6tnl_types },
-
-        [NL_UNION_LINK_INFO_DATA_VRF] =  { .count = ELEMENTSOF(rtnl_link_info_data_vrf_types),
-                                                     .types = rtnl_link_info_data_vrf_types },
-
+                                                       .types = rtnl_link_info_data_ipgre_types },
+        [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] =    { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
+                                                       .types = rtnl_link_info_data_ipgre_types },
+        [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
+                                                       .types = rtnl_link_info_data_ipgre_types },
+        [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] =       { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types),
+                                                       .types = rtnl_link_info_data_iptun_types },
+        [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] =       { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types),
+                                                       .types = rtnl_link_info_data_ipvti_types },
+        [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] =      { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types),
+                                                       .types = rtnl_link_info_data_ipvti_types },
+        [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] =    { .count = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types),
+                                                       .types = rtnl_link_info_data_ip6tnl_types },
+        [NL_UNION_LINK_INFO_DATA_VRF] =              { .count = ELEMENTSOF(rtnl_link_info_data_vrf_types),
+                                                       .types = rtnl_link_info_data_vrf_types },
 };
 
 static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = {
index 7c0e598b2626cce1c2e19c7d5797b18de1386252..42e96173de84dd3c8b1082439bba9e71c05852ff 100644 (file)
@@ -87,6 +87,7 @@ typedef enum NLUnionLinkInfoData {
         NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL,
         NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL,
         NL_UNION_LINK_INFO_DATA_VRF,
+        NL_UNION_LINK_INFO_DATA_VCAN,
         _NL_UNION_LINK_INFO_DATA_MAX,
         _NL_UNION_LINK_INFO_DATA_INVALID = -1
 } NLUnionLinkInfoData;
index aab40a0eb1a792581a176568123f24a0acb492e7..1687d9bf319e46eccc7fe9e33e9438182546bdab 100644 (file)
@@ -1787,6 +1787,31 @@ static int link_down(Link *link) {
         return 0;
 }
 
+static int link_up_can(Link *link) {
+        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
+        int r;
+
+        assert(link);
+
+        log_link_debug(link, "Bringing CAN link up");
+
+        r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
+        if (r < 0)
+                return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
+
+        r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
+        if (r < 0)
+                return log_link_error_errno(link, r, "Could not set link flags: %m");
+
+        r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
+        if (r < 0)
+                return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
+
+        link_ref(link);
+
+        return 0;
+}
+
 static int link_handle_bound_to_list(Link *link) {
         Link *l;
         Iterator i;
@@ -2431,6 +2456,19 @@ static int link_configure(Link *link) {
         assert(link->network);
         assert(link->state == LINK_STATE_PENDING);
 
+        if (streq_ptr(link->kind, "vcan")) {
+
+                if (!(link->flags & IFF_UP)) {
+                        r = link_up_can(link);
+                        if (r < 0) {
+                                link_enter_failed(link);
+                                return r;
+                        }
+                }
+
+                return 0;
+        }
+
         /* Drop foreign config, but ignore loopback or critical devices.
          * We do not want to remove loopback address or addresses used for root NFS. */
         if (!(link->flags & IFF_LOOPBACK) && !(link->network->dhcp_critical)) {
diff --git a/src/network/networkd-netdev-vcan.c b/src/network/networkd-netdev-vcan.c
new file mode 100644 (file)
index 0000000..bfce6e1
--- /dev/null
@@ -0,0 +1,25 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2016 Susant Sahani
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "networkd-netdev-vcan.h"
+
+const NetDevVTable vcan_vtable = {
+        .object_size = sizeof(VCan),
+        .create_type = NETDEV_CREATE_INDEPENDENT,
+};
diff --git a/src/network/networkd-netdev-vcan.h b/src/network/networkd-netdev-vcan.h
new file mode 100644 (file)
index 0000000..6ba47fd
--- /dev/null
@@ -0,0 +1,34 @@
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2016 Susant Sahani
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct VCan VCan;
+
+#include <linux/can/netlink.h>
+
+#include "networkd-netdev.h"
+
+struct VCan {
+        NetDev meta;
+};
+
+DEFINE_NETDEV_CAST(VCAN, VCan);
+
+extern const NetDevVTable vcan_vtable;
index e7edc366afe41b82394fb8469208a21e94b1634d..583389c8dd9e58b27e99bf763996f9b98d2b0b4b 100644 (file)
@@ -56,7 +56,7 @@ const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = {
         [NETDEV_KIND_TAP] = &tap_vtable,
         [NETDEV_KIND_IP6TNL] = &ip6tnl_vtable,
         [NETDEV_KIND_VRF] = &vrf_vtable,
-
+        [NETDEV_KIND_VCAN] = &vcan_vtable,
 };
 
 static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
@@ -81,7 +81,7 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
         [NETDEV_KIND_TAP] = "tap",
         [NETDEV_KIND_IP6TNL] = "ip6tnl",
         [NETDEV_KIND_VRF] = "vrf",
-
+        [NETDEV_KIND_VCAN] = "vcan",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind);
index 09863e72b4a28157e82945a075c79e42db85b3a5..31b55e279118b08547c1e0943a747a34088e613d 100644 (file)
@@ -56,6 +56,7 @@ typedef enum NetDevKind {
         NETDEV_KIND_TUN,
         NETDEV_KIND_TAP,
         NETDEV_KIND_VRF,
+        NETDEV_KIND_VCAN,
         _NETDEV_KIND_MAX,
         _NETDEV_KIND_INVALID = -1
 } NetDevKind;
index 49faba5b120a492a20d30d9de43bfe32a912a3e6..9865c8a5c0958ac327b09183549264f80b34dc6b 100644 (file)
@@ -479,6 +479,7 @@ int config_parse_netdev(const char *unit,
         case NETDEV_KIND_MACVTAP:
         case NETDEV_KIND_IPVLAN:
         case NETDEV_KIND_VXLAN:
+        case NETDEV_KIND_VCAN:
                 r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev);
                 if (r < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, r, "Can not add VLAN '%s' to network: %m", rvalue);
index c4bd712147d4126ba2f1eb8c80184942389dea24..cb1b73145eb03c28fc31ef4e6f06f45abe826ddb 100644 (file)
@@ -43,6 +43,7 @@
 #include "networkd-netdev-vlan.h"
 #include "networkd-netdev-vrf.h"
 #include "networkd-netdev-vxlan.h"
+#include "networkd-netdev-vcan.h"
 #include "networkd-network.h"
 #include "networkd-util.h"