summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOlegBravo <oleg.bravo.ru@gmail.com>2019-10-15 16:13:37 +0300
committerLubomir Rintel <lkundrak@v3.sk>2019-10-30 16:13:47 +0100
commit12661e2f21e9c8c68d6d174f5ff5b952e394c8a2 (patch)
treec3abfed2cb039540827e66ab322ece8a8dd58235 /src
parent5535dcf51ba759555a8e20504030dc59e526925e (diff)
downloadNetworkManager-contrail/vrouter.tar.gz
Vhost0 management integration.contrail/vrouter
Removing systemd networking configuration at RHEL8 jeopardized Contrail Virtual Router deployment (https://github.com/Juniper/contrail-vrouter ) - multiple CNI are based on this project. Problem is in configuring vhost0 - layer3 interface , used between host OS and Vrouter itself. It is being configured with systemd now , but for newest RHEL major release this functionality should be moved to NetworkManager. This will also benefit recent problems we had with OpenShift which also uses NM. Documentation was added into README.md , for new functinality testing - just follow it , creating of vhost0 interface is expted as successfull result.
Diffstat (limited to 'src')
-rw-r--r--src/devices/contrail/meson.build34
-rw-r--r--src/devices/contrail/nm-contrail-factory.c116
-rw-r--r--src/devices/contrail/nm-device-contrail-vrouter.c282
-rw-r--r--src/devices/contrail/nm-device-contrail-vrouter.h22
-rw-r--r--src/devices/meson.build4
-rw-r--r--src/devices/nm-device.c2
-rw-r--r--src/nm-types.h1
-rw-r--r--src/platform/nm-linux-platform.c78
8 files changed, 502 insertions, 37 deletions
diff --git a/src/devices/contrail/meson.build b/src/devices/contrail/meson.build
new file mode 100644
index 0000000000..c3bdf80666
--- /dev/null
+++ b/src/devices/contrail/meson.build
@@ -0,0 +1,34 @@
+sources = files(
+ 'nm-device-contrail-vrouter.c',
+ 'nm-contrail-factory.c'
+)
+
+deps = [
+ nm_deps
+]
+
+libnm_device_plugin_contrail = shared_module(
+ 'nm-device-plugin-contrail',
+ sources: sources,
+ dependencies: deps,
+ c_args: daemon_c_flags,
+ link_args: ldflags_linker_script_devices,
+ link_depends: linker_script_devices,
+ install: true,
+ install_dir: nm_plugindir
+)
+
+core_plugins += libnm_device_plugin_contrail
+
+test(
+ 'check-local-devices-contrail',
+ check_exports,
+ args: [libnm_device_plugin_contrail.full_path(), linker_script_devices],
+)
+
+# FIXME: check_so_symbols replacement
+'''
+check-local-devices-contrail: src/devices/contrail/libnm-device-plugin-contrail.la
+ $(srcdir)/tools/check-exports.sh $(builddir)/src/devices/contrail/.libs/libnm-device-plugin-contrail.so "$(srcdir)/linker-script-devices.ver"
+ $(call check_so_symbols,$(builddir)/src/devices/contrail/.libs/libnm-device-plugin-contrail.so)
+'''
diff --git a/src/devices/contrail/nm-contrail-factory.c b/src/devices/contrail/nm-contrail-factory.c
new file mode 100644
index 0000000000..dd8124849b
--- /dev/null
+++ b/src/devices/contrail/nm-contrail-factory.c
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: LGPL-2.1+
+/*
+ * Copyright (C) 2007 - 2013 Red Hat, Inc.
+ * Copyright (C) 2007 - 2008 Novell, Inc.
+ */
+
+#include "nm-default.h"
+
+#include "nm-manager.h"
+#include "nm-device-contrail-vrouter.h"
+#include "platform/nm-platform.h"
+#include "nm-core-internal.h"
+#include "devices/nm-device-factory.h"
+
+/*****************************************************************************/
+
+typedef struct {
+ NMDeviceFactory parent;
+} NMContrailFactory;
+
+typedef struct {
+ NMDeviceFactoryClass parent;
+} NMContrailFactoryClass;
+
+#define NM_TYPE_CONTRAIL_FACTORY (nm_contrail_factory_get_type ())
+#define NM_CONTRAIL_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CONTRAIL_FACTORY, NMContrailFactory))
+#define NM_CONTRAIL_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_CONTRAIL_FACTORY, NMContrailFactoryClass))
+#define NM_IS_CONTRAIL_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CONTRAIL_FACTORY))
+#define NM_IS_CONTRAIL_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_CONTRAIL_FACTORY))
+#define NM_CONTRAIL_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CONTRAIL_FACTORY, NMContrailFactoryClass))
+
+static GType nm_contrail_factory_get_type (void);
+G_DEFINE_TYPE (NMContrailFactory, nm_contrail_factory, NM_TYPE_DEVICE_FACTORY)
+
+/*****************************************************************************/
+
+#define _NMLOG_DOMAIN LOGD_DEVICE
+#define _NMLOG(level, ...) __NMLOG_DEFAULT (level, _NMLOG_DOMAIN, "contrail", __VA_ARGS__)
+
+/*****************************************************************************/
+
+NM_DEVICE_FACTORY_DECLARE_TYPES (
+ NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_CONTRAILVROUTER)
+ NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_CONTRAIL_VROUTER_SETTING_NAME)
+)
+
+G_MODULE_EXPORT NMDeviceFactory *
+nm_device_factory_create (GError **error)
+{
+ return (NMDeviceFactory *) g_object_new (NM_TYPE_CONTRAIL_FACTORY, NULL);
+}
+
+static NMDevice *
+new_device_from_type (const char *name, NMDeviceType device_type)
+{
+ GType type;
+ const char *type_desc;
+ NMLinkType link_type = NM_LINK_TYPE_NONE;
+
+ if (nm_manager_get_device (nm_manager_get (), name, device_type))
+ return NULL;
+
+ if (device_type == NM_DEVICE_TYPE_CONTRAIL_VROUTER) {
+ type = NM_TYPE_DEVICE_CONTRAIL_VROUTER;
+ type_desc = "Contrail Vrouter";
+ link_type = NM_LINK_TYPE_CONTRAILVROUTER;
+ } else {
+ return NULL;
+ }
+
+ return g_object_new (type,
+ NM_DEVICE_IFACE, name,
+ NM_DEVICE_DRIVER, "vrouter",
+ NM_DEVICE_DEVICE_TYPE, device_type,
+ NM_DEVICE_TYPE_DESC, type_desc,
+ NM_DEVICE_LINK_TYPE, link_type,
+ NULL);
+}
+
+static NMDevice *
+create_device (NMDeviceFactory *self,
+ const char *iface,
+ const NMPlatformLink *plink,
+ NMConnection *connection,
+ gboolean *out_ignore)
+{
+ NMDeviceType device_type = NM_DEVICE_TYPE_UNKNOWN;
+ const char *connection_type = NULL;
+
+ if (connection)
+ connection_type = nm_connection_get_connection_type (connection);
+
+ if (plink)
+ device_type = NM_DEVICE_TYPE_CONTRAIL_VROUTER;
+ else if (g_strcmp0 (connection_type, NM_SETTING_CONTRAIL_VROUTER_SETTING_NAME) == 0)
+ device_type = NM_DEVICE_TYPE_CONTRAIL_VROUTER;
+
+ return new_device_from_type (iface, device_type);
+}
+
+static void
+nm_contrail_factory_init (NMContrailFactory *self)
+{
+}
+
+static void
+nm_contrail_factory_class_init (NMContrailFactoryClass *klass)
+{
+ NMDeviceFactoryClass *factory_class = NM_DEVICE_FACTORY_CLASS (klass);
+
+ factory_class->get_supported_types = get_supported_types;
+ factory_class->create_device = create_device;
+ // TODO reload funcs:
+// factory_class->device_removed = device_removed;
+// factory_class->device_added = device_added;
+}
diff --git a/src/devices/contrail/nm-device-contrail-vrouter.c b/src/devices/contrail/nm-device-contrail-vrouter.c
new file mode 100644
index 0000000000..773d631855
--- /dev/null
+++ b/src/devices/contrail/nm-device-contrail-vrouter.c
@@ -0,0 +1,282 @@
+// SPDX-License-Identifier: LGPL-2.1+
+/*
+ * Copyright (C) 2007 - 2013 Red Hat, Inc.
+ * Copyright (C) 2007 - 2008 Novell, Inc.
+ */
+
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <unistd.h>
+
+#include "nm-default.h"
+
+#include "nm-device-contrail-vrouter.h"
+
+#include "devices/nm-device-private.h"
+#include "nm-active-connection.h"
+#include "nm-setting-connection.h"
+#include "nm-setting-contrail-vrouter.h"
+
+#include "devices/nm-device-logging.h"
+_LOG_DECLARE_SELF(NMDeviceContrailVrouter);
+
+/*****************************************************************************/
+
+typedef struct {
+ bool waiting_for_interface:1;
+} NMDeviceContrailVrouterPrivate;
+
+struct _NMDeviceContrailVrouter {
+ NMDevice parent;
+ NMDeviceContrailVrouterPrivate _priv;
+};
+
+struct _NMDeviceContrailVrouterClass {
+ NMDeviceClass parent;
+};
+
+G_DEFINE_TYPE (NMDeviceContrailVrouter, nm_device_contrail_vrouter, NM_TYPE_DEVICE)
+
+#define NM_DEVICE_CONTRAIL_VROUTER_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceContrailVrouter, NM_IS_DEVICE_CONTRAIL_VROUTER, NMDevice)
+
+/*****************************************************************************/
+
+void _get_command(const char *iface,
+ const char *physdev,
+ char *command,
+ const int command_size);
+
+void
+_get_mac (const char *physdev, char *mac_str);
+
+void
+_get_mac (const char *physdev, char *mac_str)
+{
+ struct ifreq ifr;
+ int fd;
+ unsigned char *mac;
+ int i;
+ char *pos;
+
+ nm_log_dbg (LOGD_DEVICE, "CONTRAIL: %s %s", __FILE__ , __func__);
+
+ memset(&ifr, 0, sizeof(ifr));
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ ifr.ifr_addr.sa_family = AF_INET;
+ strncpy(ifr.ifr_name , physdev , IFNAMSIZ-1);
+ if (0 == ioctl(fd, SIOCGIFHWADDR, &ifr)) {
+ mac = (unsigned char *)ifr.ifr_hwaddr.sa_data;
+ i = 0;
+ pos = mac_str;
+ for ( ; i < 6; i++) {
+ if (i) {
+ pos += sprintf(pos, ":");
+ }
+ pos += sprintf(pos, "%02X", (unsigned char)mac[i]);
+ }
+ }
+ close(fd);
+}
+
+void
+_get_command (const char *iface,
+ const char *physdev,
+ char *command,
+ const int command_size)
+{
+ char mac_str[19];
+
+ nm_log_dbg (LOGD_DEVICE, "CONTRAIL: %s %s", __FILE__ , __func__);
+
+ _get_mac(physdev, mac_str);
+ nm_log_dbg (LOGD_DEVICE, "CONTRAIL: mac address: %s", mac_str);
+
+ snprintf(command, command_size,
+ "modprobe vrouter && "
+ "vif --create %s --mac %s 2>&1 && "
+ "vif --add %s --mac %s --vrf 0 --vhost-phys --type physical 2>&1 && "
+ "vif --add %s --mac %s --vrf 0 --type vhost --xconnect %s 2>&1 && "
+ "ip link set dev %s address %s 2>&1 && "
+ "ip link set dev %s up 2>&1",
+ iface, mac_str,
+ physdev, mac_str,
+ iface, mac_str, physdev,
+ iface, mac_str,
+ iface);
+}
+
+/*********************************************************************************/
+
+static const char *
+get_type_description (NMDevice *device)
+{
+ nm_log_dbg (LOGD_DEVICE, "CONTRAIL: %s %s", __FILE__ , __func__);
+
+ return "contrail-vrouter";
+}
+
+static gboolean
+create_and_realize (NMDevice *device,
+ NMConnection *connection,
+ NMDevice *parent,
+ const NMPlatformLink **out_plink,
+ GError **error)
+{
+ nm_log_dbg (LOGD_DEVICE, "CONTRAIL: %s %s", __FILE__ , __func__);
+
+ return TRUE;
+}
+
+static NMDeviceCapabilities
+get_generic_capabilities (NMDevice *device)
+{
+ nm_log_dbg (LOGD_DEVICE, "CONTRAIL: %s %s", __FILE__ , __func__);
+
+ return NM_DEVICE_CAP_IS_SOFTWARE;
+}
+
+static gboolean
+is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
+{
+ nm_log_dbg (LOGD_DEVICE, "CONTRAIL: %s %s", __FILE__ , __func__);
+
+ return TRUE;
+}
+
+static gboolean
+check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
+{
+ nm_log_dbg (LOGD_DEVICE, "CONTRAIL: %s %s", __FILE__ , __func__);
+
+ return TRUE;
+}
+
+static void
+link_changed (NMDevice *device,
+ const NMPlatformLink *pllink)
+{
+ NMDeviceContrailVrouterPrivate *priv;
+
+ nm_log_dbg (LOGD_DEVICE, "CONTRAIL: %s %s", __FILE__ , __func__);
+ priv = NM_DEVICE_CONTRAIL_VROUTER_GET_PRIVATE (device);
+
+ if (pllink && priv->waiting_for_interface) {
+ priv->waiting_for_interface = FALSE;
+ nm_device_bring_up (device, TRUE, NULL);
+ nm_device_activate_schedule_stage3_ip_config_start (device);
+ }
+}
+
+static NMActStageReturn
+act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
+{
+ FILE *fp;
+ int COMMAND_OUTPUT_SIZE = 512;
+ char output[COMMAND_OUTPUT_SIZE];
+ const char *iface;
+ int COMMAND_SIZE = 512;
+ char command[COMMAND_SIZE];
+ const char *physdev;
+ NMConnection *connection;
+
+ nm_log_dbg (LOGD_DEVICE, "CONTRAIL: %s %s", __FILE__ , __func__);
+
+ if (!device) {
+ nm_log_err (LOGD_DEVICE, "CONTRAIL: device is null");
+ return NM_ACT_STAGE_RETURN_FAILURE;
+ }
+ connection = nm_device_get_applied_connection (device);
+ if (!connection) {
+ nm_log_err (LOGD_DEVICE, "CONTRAIL: connection is null");
+ return NM_ACT_STAGE_RETURN_FAILURE;
+ }
+ nm_connection_dump (connection);
+ iface = nm_connection_get_interface_name (connection);
+ nm_log_dbg (LOGD_DEVICE, "CONTRAIL: interface name: %s", iface);
+ physdev = nm_setting_contrail_vrouter_get_physdev (nm_connection_get_setting_contrail_vrouter (connection));
+ if (physdev) {
+ nm_log_dbg (LOGD_DEVICE, "CONTRAIL: physical device name: %s", physdev);
+ _get_command(iface, physdev, command, COMMAND_SIZE);
+ nm_log_dbg (LOGD_DEVICE, "CONTRAIL: vrouter command: %s", command);
+ fp = popen(command, "r");
+ while (fgets(output, COMMAND_OUTPUT_SIZE, fp) != NULL){
+ nm_log_err (LOGD_DEVICE, "CONTRAIL: %s", output);
+ }
+ pclose(fp);
+ }
+ else {
+ nm_log_err (LOGD_DEVICE, "CONTRAIL: physical device name was not provided.");
+ return NM_ACT_STAGE_RETURN_FAILURE;
+ }
+ return NM_ACT_STAGE_RETURN_SUCCESS;
+}
+
+static NMActStageReturn
+act_stage3_ip_config_start (NMDevice *device,
+ int addr_family,
+ gpointer *out_config,
+ NMDeviceStateReason *out_failure_reason)
+{
+ NMDeviceContrailVrouterPrivate *priv;
+
+ nm_log_dbg (LOGD_DEVICE, "CONTRAIL: %s %s", __FILE__ , __func__);
+ priv = NM_DEVICE_CONTRAIL_VROUTER_GET_PRIVATE (device);
+
+ if (!nm_device_get_ip_ifindex (device)) {
+ priv->waiting_for_interface = TRUE;
+ return NM_ACT_STAGE_RETURN_POSTPONE;
+ }
+
+ return NM_DEVICE_CLASS (nm_device_contrail_vrouter_parent_class)->act_stage3_ip_config_start (device, addr_family, out_config, out_failure_reason);
+}
+
+static gboolean
+can_unmanaged_external_down (NMDevice *self)
+{
+ nm_log_dbg (LOGD_DEVICE, "CONTRAIL: %s %s", __FILE__ , __func__);
+
+ return FALSE;
+}
+
+/*****************************************************************************/
+
+static void
+nm_device_contrail_vrouter_init (NMDeviceContrailVrouter *self)
+{
+ nm_log_dbg (LOGD_DEVICE, "CONTRAIL: %s %s", __FILE__ , __func__);
+}
+
+static const NMDBusInterfaceInfoExtended interface_info_device_contrail_vrouter = {
+ .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT (
+ NM_DBUS_INTERFACE_DEVICE_CONTRAIL_VROUTER,
+ .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS (
+ &nm_signal_info_property_changed_legacy,
+ ),
+ ),
+ .legacy_property_changed = TRUE,
+};
+
+static void
+nm_device_contrail_vrouter_class_init (NMDeviceContrailVrouterClass *klass)
+{
+ NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass);
+ NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
+
+ dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_contrail_vrouter);
+
+ device_class->connection_type_supported = NM_SETTING_CONTRAIL_VROUTER_SETTING_NAME;
+ device_class->connection_type_check_compatible = NM_SETTING_CONTRAIL_VROUTER_SETTING_NAME;
+ device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_CONTRAILVROUTER);
+
+ device_class->get_type_description = get_type_description;
+ device_class->create_and_realize = create_and_realize;
+ device_class->get_generic_capabilities = get_generic_capabilities;
+ device_class->is_available = is_available;
+ device_class->check_connection_compatible = check_connection_compatible;
+ device_class->link_changed = link_changed;
+ device_class->act_stage1_prepare = act_stage1_prepare;
+ device_class->act_stage3_ip_config_start = act_stage3_ip_config_start;
+ device_class->can_unmanaged_external_down = can_unmanaged_external_down;
+}
diff --git a/src/devices/contrail/nm-device-contrail-vrouter.h b/src/devices/contrail/nm-device-contrail-vrouter.h
new file mode 100644
index 0000000000..05b9dc954a
--- /dev/null
+++ b/src/devices/contrail/nm-device-contrail-vrouter.h
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: LGPL-2.1+
+/*
+ * Copyright (C) 2007 - 2013 Red Hat, Inc.
+ * Copyright (C) 2007 - 2008 Novell, Inc.
+ */
+
+#ifndef __NETWORKMANAGER_DEVICE_CONTRAIL_VROUTER_H__
+#define __NETWORKMANAGER_DEVICE_CONTRAIL_VROUTER_H__
+
+#define NM_TYPE_DEVICE_CONTRAIL_VROUTER (nm_device_contrail_vrouter_get_type ())
+#define NM_DEVICE_CONTRAIL_VROUTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_CONTRAIL_VROUTER, NMDeviceContrailVrouter))
+#define NM_DEVICE_CONTRAIL_VROUTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_CONTRAIL_VROUTER, NMDeviceContrailVrouterClass))
+#define NM_IS_DEVICE_CONTRAIL_VROUTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_CONTRAIL_VROUTER))
+#define NM_IS_DEVICE_CONTRAIL_VROUTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_CONTRAIL_VROUTER))
+#define NM_DEVICE_CONTRAIL_VROUTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_CONTRAIL_VROUTER, NMDeviceContrailVrouterClass))
+
+typedef struct _NMDeviceContrailVrouter NMDeviceContrailVrouter;
+typedef struct _NMDeviceContrailVrouterClass NMDeviceContrailVrouterClass;
+
+GType nm_device_contrail_vrouter_get_type (void);
+
+#endif /* __NETWORKMANAGER_DEVICE_CONTRAIL_VROUTER_H__ */
diff --git a/src/devices/meson.build b/src/devices/meson.build
index 2d874659c7..d29bf5e5ef 100644
--- a/src/devices/meson.build
+++ b/src/devices/meson.build
@@ -20,3 +20,7 @@ endif
if enable_tests
subdir('tests')
endif
+
+if enable_contrail
+ subdir('contrail')
+endif
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 96fc6614ac..6c259f83a0 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -774,6 +774,7 @@ NM_UTILS_LOOKUP_STR_DEFINE (nm_device_state_reason_to_str, NMDeviceStateReason,
NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED, "ip-method-unsupported"),
NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED, "sriov-configuration-failed"),
NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_PEER_NOT_FOUND, "peer-not-found"),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_CONTRAIL_VROUTER_FAILED, "contrail-vrouter-failed"),
);
#define reason_to_string_a(reason) NM_UTILS_LOOKUP_STR_A (nm_device_state_reason_to_str, reason)
@@ -2134,6 +2135,7 @@ nm_device_get_route_metric_default (NMDeviceType device_type)
return 10000;
case NM_DEVICE_TYPE_UNUSED1:
case NM_DEVICE_TYPE_UNUSED2:
+ case NM_DEVICE_TYPE_CONTRAIL_VROUTER:
/* omit default: to get compiler warning about missing switch cases */
break;
}
diff --git a/src/nm-types.h b/src/nm-types.h
index 2f1ac2dcd5..034f98a565 100644
--- a/src/nm-types.h
+++ b/src/nm-types.h
@@ -162,6 +162,7 @@ typedef enum {
NM_LINK_TYPE_VLAN,
NM_LINK_TYPE_VXLAN,
NM_LINK_TYPE_WIREGUARD,
+ NM_LINK_TYPE_CONTRAILVROUTER,
/* Software types with slaves */
NM_LINK_TYPE_BRIDGE = 0x10000 | 0x20000,
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index 305ae52e3a..8a35e9e979 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -624,43 +624,44 @@ typedef struct {
} LinkDesc;
static const LinkDesc linktypes[] = {
- { NM_LINK_TYPE_NONE, "none", NULL, NULL },
- { NM_LINK_TYPE_UNKNOWN, "unknown", NULL, NULL },
-
- { NM_LINK_TYPE_ETHERNET, "ethernet", NULL, NULL },
- { NM_LINK_TYPE_INFINIBAND, "infiniband", NULL, NULL },
- { NM_LINK_TYPE_OLPC_MESH, "olpc-mesh", NULL, NULL },
- { NM_LINK_TYPE_WIFI, "wifi", NULL, "wlan" },
- { NM_LINK_TYPE_WWAN_NET, "wwan", NULL, "wwan" },
- { NM_LINK_TYPE_WIMAX, "wimax", "wimax", "wimax" },
- { NM_LINK_TYPE_WPAN, "wpan", NULL, NULL },
- { NM_LINK_TYPE_6LOWPAN, "6lowpan", NULL, NULL },
-
- { NM_LINK_TYPE_BNEP, "bluetooth", NULL, "bluetooth" },
- { NM_LINK_TYPE_DUMMY, "dummy", "dummy", NULL },
- { NM_LINK_TYPE_GRE, "gre", "gre", NULL },
- { NM_LINK_TYPE_GRETAP, "gretap", "gretap", NULL },
- { NM_LINK_TYPE_IFB, "ifb", "ifb", NULL },
- { NM_LINK_TYPE_IP6TNL, "ip6tnl", "ip6tnl", NULL },
- { NM_LINK_TYPE_IP6GRE, "ip6gre", "ip6gre", NULL },
- { NM_LINK_TYPE_IP6GRETAP, "ip6gretap", "ip6gretap", NULL },
- { NM_LINK_TYPE_IPIP, "ipip", "ipip", NULL },
- { NM_LINK_TYPE_LOOPBACK, "loopback", NULL, NULL },
- { NM_LINK_TYPE_MACSEC, "macsec", "macsec", NULL },
- { NM_LINK_TYPE_MACVLAN, "macvlan", "macvlan", NULL },
- { NM_LINK_TYPE_MACVTAP, "macvtap", "macvtap", NULL },
- { NM_LINK_TYPE_OPENVSWITCH, "openvswitch", "openvswitch", NULL },
- { NM_LINK_TYPE_PPP, "ppp", NULL, "ppp" },
- { NM_LINK_TYPE_SIT, "sit", "sit", NULL },
- { NM_LINK_TYPE_TUN, "tun", "tun", NULL },
- { NM_LINK_TYPE_VETH, "veth", "veth", NULL },
- { NM_LINK_TYPE_VLAN, "vlan", "vlan", "vlan" },
- { NM_LINK_TYPE_VXLAN, "vxlan", "vxlan", "vxlan" },
- { NM_LINK_TYPE_WIREGUARD, "wireguard", "wireguard", "wireguard" },
-
- { NM_LINK_TYPE_BRIDGE, "bridge", "bridge", "bridge" },
- { NM_LINK_TYPE_BOND, "bond", "bond", "bond" },
- { NM_LINK_TYPE_TEAM, "team", "team", NULL },
+ { NM_LINK_TYPE_NONE, "none", NULL, NULL },
+ { NM_LINK_TYPE_UNKNOWN, "unknown", NULL, NULL },
+
+ { NM_LINK_TYPE_ETHERNET, "ethernet", NULL, NULL },
+ { NM_LINK_TYPE_INFINIBAND, "infiniband", NULL, NULL },
+ { NM_LINK_TYPE_OLPC_MESH, "olpc-mesh", NULL, NULL },
+ { NM_LINK_TYPE_WIFI, "wifi", NULL, "wlan" },
+ { NM_LINK_TYPE_WWAN_NET, "wwan", NULL, "wwan" },
+ { NM_LINK_TYPE_WIMAX, "wimax", "wimax", "wimax" },
+ { NM_LINK_TYPE_WPAN, "wpan", NULL, NULL },
+ { NM_LINK_TYPE_6LOWPAN, "6lowpan", NULL, NULL },
+
+ { NM_LINK_TYPE_BNEP, "bluetooth", NULL, "bluetooth" },
+ { NM_LINK_TYPE_DUMMY, "dummy", "dummy", NULL },
+ { NM_LINK_TYPE_GRE, "gre", "gre", NULL },
+ { NM_LINK_TYPE_GRETAP, "gretap", "gretap", NULL },
+ { NM_LINK_TYPE_IFB, "ifb", "ifb", NULL },
+ { NM_LINK_TYPE_IP6TNL, "ip6tnl", "ip6tnl", NULL },
+ { NM_LINK_TYPE_IP6GRE, "ip6gre", "ip6gre", NULL },
+ { NM_LINK_TYPE_IP6GRETAP, "ip6gretap", "ip6gretap", NULL },
+ { NM_LINK_TYPE_IPIP, "ipip", "ipip", NULL },
+ { NM_LINK_TYPE_LOOPBACK, "loopback", NULL, NULL },
+ { NM_LINK_TYPE_MACSEC, "macsec", "macsec", NULL },
+ { NM_LINK_TYPE_MACVLAN, "macvlan", "macvlan", NULL },
+ { NM_LINK_TYPE_MACVTAP, "macvtap", "macvtap", NULL },
+ { NM_LINK_TYPE_OPENVSWITCH, "openvswitch", "openvswitch", NULL },
+ { NM_LINK_TYPE_PPP, "ppp", NULL, "ppp" },
+ { NM_LINK_TYPE_SIT, "sit", "sit", NULL },
+ { NM_LINK_TYPE_TUN, "tun", "tun", NULL },
+ { NM_LINK_TYPE_VETH, "veth", "veth", NULL },
+ { NM_LINK_TYPE_VLAN, "vlan", "vlan", "vlan" },
+ { NM_LINK_TYPE_VXLAN, "vxlan", "vxlan", "vxlan" },
+ { NM_LINK_TYPE_WIREGUARD, "wireguard", "wireguard", "wireguard" },
+ { NM_LINK_TYPE_CONTRAILVROUTER, "contrailvrouter", "contrailvrouter", NULL },
+
+ { NM_LINK_TYPE_BRIDGE, "bridge", "bridge", "bridge" },
+ { NM_LINK_TYPE_BOND, "bond", "bond", "bond" },
+ { NM_LINK_TYPE_TEAM, "team", "team", NULL },
};
static const char *
@@ -966,6 +967,9 @@ _linktype_get_type (NMPlatform *platform,
if (nm_streq (driver_info.driver, "openvswitch"))
return NM_LINK_TYPE_OPENVSWITCH;
+ if (nm_streq (driver_info.driver, "vrouter"))
+ return NM_LINK_TYPE_CONTRAILVROUTER;
+
if (arptype == 256) {
/* Some s390 CTC-type devices report 256 for the encapsulation type
* for some reason, but we need to call them Ethernet.