summaryrefslogtreecommitdiff
path: root/src/devices/contrail/nm-device-contrail-vrouter.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/contrail/nm-device-contrail-vrouter.c')
-rw-r--r--src/devices/contrail/nm-device-contrail-vrouter.c282
1 files changed, 282 insertions, 0 deletions
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;
+}