summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
authorSusant Sahani <ssahani@users.noreply.github.com>2016-09-14 21:45:16 +0530
committerMartin Pitt <martin.pitt@ubuntu.com>2016-09-14 18:15:16 +0200
commit92c918b06d970cd4ce2e7e529e6093ffc46a9cfa (patch)
treed5ab7b55f7f247cd14ec6a992bf5657e466f71d3 /src/network
parent2d88def9593b9809c71039bee67bea150ddd3598 (diff)
networkd: add support to configure virtual CAN device (#4139)
1. add support for kind vcan 2. fixup indention netlink-types.c, networkd-netdev.c
Diffstat (limited to 'src/network')
-rw-r--r--src/network/networkd-link.c38
-rw-r--r--src/network/networkd-netdev-vcan.c25
-rw-r--r--src/network/networkd-netdev-vcan.h34
-rw-r--r--src/network/networkd-netdev.c4
-rw-r--r--src/network/networkd-netdev.h1
-rw-r--r--src/network/networkd-network.c1
-rw-r--r--src/network/networkd.h1
7 files changed, 102 insertions, 2 deletions
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index aab40a0eb1..1687d9bf31 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -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
index 0000000000..bfce6e1962
--- /dev/null
+++ b/src/network/networkd-netdev-vcan.c
@@ -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
index 0000000000..6ba47fd70e
--- /dev/null
+++ b/src/network/networkd-netdev-vcan.h
@@ -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;
diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c
index e7edc366af..583389c8dd 100644
--- a/src/network/networkd-netdev.c
+++ b/src/network/networkd-netdev.c
@@ -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);
diff --git a/src/network/networkd-netdev.h b/src/network/networkd-netdev.h
index 09863e72b4..31b55e2791 100644
--- a/src/network/networkd-netdev.h
+++ b/src/network/networkd-netdev.h
@@ -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;
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 49faba5b12..9865c8a5c0 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -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);
diff --git a/src/network/networkd.h b/src/network/networkd.h
index c4bd712147..cb1b73145e 100644
--- a/src/network/networkd.h
+++ b/src/network/networkd.h
@@ -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"