Skip to content

Commit 92c918b

Browse files
ssahanimartinpitt
authored andcommitted
networkd: add support to configure virtual CAN device (systemd#4139)
1. add support for kind vcan 2. fixup indention netlink-types.c, networkd-netdev.c
1 parent 2d88def commit 92c918b

File tree

11 files changed

+147
-40
lines changed

11 files changed

+147
-40
lines changed

Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5650,6 +5650,8 @@ libnetworkd_core_la_SOURCES = \
56505650
src/network/networkd-netdev-bond.c \
56515651
src/network/networkd-netdev-bridge.h \
56525652
src/network/networkd-netdev-bridge.c \
5653+
src/network/networkd-netdev-vcan.h \
5654+
src/network/networkd-netdev-vcan.c \
56535655
src/network/networkd-link-bus.c \
56545656
src/network/networkd-ipv4ll.c \
56555657
src/network/networkd-dhcp4.c \

man/systemd.netdev.xml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,11 @@
163163
<entry>A virtual extensible LAN (vxlan), for connecting Cloud computing deployments.</entry></row>
164164

165165
<row><entry><varname>vrf</varname></entry>
166-
<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>
166+
<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>
167+
168+
<row><entry><varname>vcan</varname></entry>
169+
<entry>The virtual CAN driver (vcan). Similar to the network loopback devices,
170+
vcan offers a virtual local CAN interface.</entry></row>
167171

168172
</tbody>
169173
</tgroup>

src/libsystemd/sd-netlink/netlink-types.c

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <sys/socket.h>
2222
#include <linux/netlink.h>
2323
#include <linux/rtnetlink.h>
24+
#include <linux/can/netlink.h>
2425
#include <linux/in6.h>
2526
#include <linux/veth.h>
2627
#include <linux/if_bridge.h>
@@ -303,49 +304,48 @@ static const char* const nl_union_link_info_data_table[] = {
303304
[NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = "vti6",
304305
[NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = "ip6tnl",
305306
[NL_UNION_LINK_INFO_DATA_VRF] = "vrf",
307+
[NL_UNION_LINK_INFO_DATA_VCAN] = "vcan",
306308
};
307309

308310
DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData);
309311

310312
static const NLTypeSystem rtnl_link_info_data_type_systems[] = {
311-
[NL_UNION_LINK_INFO_DATA_BOND] = { .count = ELEMENTSOF(rtnl_link_info_data_bond_types),
312-
.types = rtnl_link_info_data_bond_types },
313-
[NL_UNION_LINK_INFO_DATA_BRIDGE] = { .count = ELEMENTSOF(rtnl_link_info_data_bridge_types),
314-
.types = rtnl_link_info_data_bridge_types },
315-
[NL_UNION_LINK_INFO_DATA_VLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vlan_types),
316-
.types = rtnl_link_info_data_vlan_types },
317-
[NL_UNION_LINK_INFO_DATA_VETH] = { .count = ELEMENTSOF(rtnl_link_info_data_veth_types),
318-
.types = rtnl_link_info_data_veth_types },
319-
[NL_UNION_LINK_INFO_DATA_MACVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types),
320-
.types = rtnl_link_info_data_macvlan_types },
321-
[NL_UNION_LINK_INFO_DATA_MACVTAP] = { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types),
322-
.types = rtnl_link_info_data_macvlan_types },
323-
[NL_UNION_LINK_INFO_DATA_IPVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types),
324-
.types = rtnl_link_info_data_ipvlan_types },
325-
[NL_UNION_LINK_INFO_DATA_VXLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vxlan_types),
326-
.types = rtnl_link_info_data_vxlan_types },
327-
[NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types),
328-
.types = rtnl_link_info_data_iptun_types },
329-
[NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
330-
.types = rtnl_link_info_data_ipgre_types },
313+
[NL_UNION_LINK_INFO_DATA_BOND] = { .count = ELEMENTSOF(rtnl_link_info_data_bond_types),
314+
.types = rtnl_link_info_data_bond_types },
315+
[NL_UNION_LINK_INFO_DATA_BRIDGE] = { .count = ELEMENTSOF(rtnl_link_info_data_bridge_types),
316+
.types = rtnl_link_info_data_bridge_types },
317+
[NL_UNION_LINK_INFO_DATA_VLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vlan_types),
318+
.types = rtnl_link_info_data_vlan_types },
319+
[NL_UNION_LINK_INFO_DATA_VETH] = { .count = ELEMENTSOF(rtnl_link_info_data_veth_types),
320+
.types = rtnl_link_info_data_veth_types },
321+
[NL_UNION_LINK_INFO_DATA_MACVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types),
322+
.types = rtnl_link_info_data_macvlan_types },
323+
[NL_UNION_LINK_INFO_DATA_MACVTAP] = { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types),
324+
.types = rtnl_link_info_data_macvlan_types },
325+
[NL_UNION_LINK_INFO_DATA_IPVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types),
326+
.types = rtnl_link_info_data_ipvlan_types },
327+
[NL_UNION_LINK_INFO_DATA_VXLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vxlan_types),
328+
.types = rtnl_link_info_data_vxlan_types },
329+
[NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types),
330+
.types = rtnl_link_info_data_iptun_types },
331+
[NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
332+
.types = rtnl_link_info_data_ipgre_types },
331333
[NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
332-
.types = rtnl_link_info_data_ipgre_types },
333-
[NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
334-
.types = rtnl_link_info_data_ipgre_types },
335-
[NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
336-
.types = rtnl_link_info_data_ipgre_types },
337-
[NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types),
338-
.types = rtnl_link_info_data_iptun_types },
339-
[NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types),
340-
.types = rtnl_link_info_data_ipvti_types },
341-
[NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types),
342-
.types = rtnl_link_info_data_ipvti_types },
343-
[NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types),
344-
.types = rtnl_link_info_data_ip6tnl_types },
345-
346-
[NL_UNION_LINK_INFO_DATA_VRF] = { .count = ELEMENTSOF(rtnl_link_info_data_vrf_types),
347-
.types = rtnl_link_info_data_vrf_types },
348-
334+
.types = rtnl_link_info_data_ipgre_types },
335+
[NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
336+
.types = rtnl_link_info_data_ipgre_types },
337+
[NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types),
338+
.types = rtnl_link_info_data_ipgre_types },
339+
[NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types),
340+
.types = rtnl_link_info_data_iptun_types },
341+
[NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types),
342+
.types = rtnl_link_info_data_ipvti_types },
343+
[NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types),
344+
.types = rtnl_link_info_data_ipvti_types },
345+
[NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types),
346+
.types = rtnl_link_info_data_ip6tnl_types },
347+
[NL_UNION_LINK_INFO_DATA_VRF] = { .count = ELEMENTSOF(rtnl_link_info_data_vrf_types),
348+
.types = rtnl_link_info_data_vrf_types },
349349
};
350350

351351
static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = {

src/libsystemd/sd-netlink/netlink-types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ typedef enum NLUnionLinkInfoData {
8787
NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL,
8888
NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL,
8989
NL_UNION_LINK_INFO_DATA_VRF,
90+
NL_UNION_LINK_INFO_DATA_VCAN,
9091
_NL_UNION_LINK_INFO_DATA_MAX,
9192
_NL_UNION_LINK_INFO_DATA_INVALID = -1
9293
} NLUnionLinkInfoData;

src/network/networkd-link.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1787,6 +1787,31 @@ static int link_down(Link *link) {
17871787
return 0;
17881788
}
17891789

1790+
static int link_up_can(Link *link) {
1791+
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
1792+
int r;
1793+
1794+
assert(link);
1795+
1796+
log_link_debug(link, "Bringing CAN link up");
1797+
1798+
r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
1799+
if (r < 0)
1800+
return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
1801+
1802+
r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1803+
if (r < 0)
1804+
return log_link_error_errno(link, r, "Could not set link flags: %m");
1805+
1806+
r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1807+
if (r < 0)
1808+
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
1809+
1810+
link_ref(link);
1811+
1812+
return 0;
1813+
}
1814+
17901815
static int link_handle_bound_to_list(Link *link) {
17911816
Link *l;
17921817
Iterator i;
@@ -2431,6 +2456,19 @@ static int link_configure(Link *link) {
24312456
assert(link->network);
24322457
assert(link->state == LINK_STATE_PENDING);
24332458

2459+
if (streq_ptr(link->kind, "vcan")) {
2460+
2461+
if (!(link->flags & IFF_UP)) {
2462+
r = link_up_can(link);
2463+
if (r < 0) {
2464+
link_enter_failed(link);
2465+
return r;
2466+
}
2467+
}
2468+
2469+
return 0;
2470+
}
2471+
24342472
/* Drop foreign config, but ignore loopback or critical devices.
24352473
* We do not want to remove loopback address or addresses used for root NFS. */
24362474
if (!(link->flags & IFF_LOOPBACK) && !(link->network->dhcp_critical)) {

src/network/networkd-netdev-vcan.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/***
2+
This file is part of systemd.
3+
4+
Copyright 2016 Susant Sahani
5+
6+
systemd is free software; you can redistribute it and/or modify it
7+
under the terms of the GNU Lesser General Public License as published by
8+
the Free Software Foundation; either version 2.1 of the License, or
9+
(at your option) any later version.
10+
11+
systemd is distributed in the hope that it will be useful, but
12+
WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
Lesser General Public License for more details.
15+
16+
You should have received a copy of the GNU Lesser General Public License
17+
along with systemd; If not, see <http://www.gnu.org/licenses/>.
18+
***/
19+
20+
#include "networkd-netdev-vcan.h"
21+
22+
const NetDevVTable vcan_vtable = {
23+
.object_size = sizeof(VCan),
24+
.create_type = NETDEV_CREATE_INDEPENDENT,
25+
};

src/network/networkd-netdev-vcan.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#pragma once
2+
3+
/***
4+
This file is part of systemd.
5+
6+
Copyright 2016 Susant Sahani
7+
8+
systemd is free software; you can redistribute it and/or modify it
9+
under the terms of the GNU Lesser General Public License as published by
10+
the Free Software Foundation; either version 2.1 of the License, or
11+
(at your option) any later version.
12+
13+
systemd is distributed in the hope that it will be useful, but
14+
WITHOUT ANY WARRANTY; without even the implied warranty of
15+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
Lesser General Public License for more details.
17+
18+
You should have received a copy of the GNU Lesser General Public License
19+
along with systemd; If not, see <http://www.gnu.org/licenses/>.
20+
***/
21+
22+
typedef struct VCan VCan;
23+
24+
#include <linux/can/netlink.h>
25+
26+
#include "networkd-netdev.h"
27+
28+
struct VCan {
29+
NetDev meta;
30+
};
31+
32+
DEFINE_NETDEV_CAST(VCAN, VCan);
33+
34+
extern const NetDevVTable vcan_vtable;

src/network/networkd-netdev.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = {
5656
[NETDEV_KIND_TAP] = &tap_vtable,
5757
[NETDEV_KIND_IP6TNL] = &ip6tnl_vtable,
5858
[NETDEV_KIND_VRF] = &vrf_vtable,
59-
59+
[NETDEV_KIND_VCAN] = &vcan_vtable,
6060
};
6161

6262
static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
@@ -81,7 +81,7 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
8181
[NETDEV_KIND_TAP] = "tap",
8282
[NETDEV_KIND_IP6TNL] = "ip6tnl",
8383
[NETDEV_KIND_VRF] = "vrf",
84-
84+
[NETDEV_KIND_VCAN] = "vcan",
8585
};
8686

8787
DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind);

src/network/networkd-netdev.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ typedef enum NetDevKind {
5656
NETDEV_KIND_TUN,
5757
NETDEV_KIND_TAP,
5858
NETDEV_KIND_VRF,
59+
NETDEV_KIND_VCAN,
5960
_NETDEV_KIND_MAX,
6061
_NETDEV_KIND_INVALID = -1
6162
} NetDevKind;

src/network/networkd-network.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,7 @@ int config_parse_netdev(const char *unit,
479479
case NETDEV_KIND_MACVTAP:
480480
case NETDEV_KIND_IPVLAN:
481481
case NETDEV_KIND_VXLAN:
482+
case NETDEV_KIND_VCAN:
482483
r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev);
483484
if (r < 0) {
484485
log_syntax(unit, LOG_ERR, filename, line, r, "Can not add VLAN '%s' to network: %m", rvalue);

0 commit comments

Comments
 (0)