/** * nm_device_tun_get_mode: * @device: a #NMDeviceTun * * Returns the TUN/TAP mode for the device. * * Returns: 'tun' or 'tap' * * Since: 1.2 **/ const char * nm_device_tun_get_mode (NMDeviceTun *device) { g_return_val_if_fail (NM_IS_DEVICE_TUN (device), NULL); return NM_DEVICE_TUN_GET_PRIVATE (device)->mode; }
/** * nm_device_tun_get_multi_queue: * @device: a #NMDeviceTun * * Returns whether the #NMDeviceTun has the IFF_MULTI_QUEUE flag. * * Returns: %TRUE if the device doesn't have the flag, %FALSE otherwise * * Since: 1.2 **/ gboolean nm_device_tun_get_multi_queue (NMDeviceTun *device) { g_return_val_if_fail (NM_IS_DEVICE_TUN (device), FALSE); return NM_DEVICE_TUN_GET_PRIVATE (device)->multi_queue; }
static gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error) { NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (device); NMSettingTunMode mode; NMSettingTun *s_tun; if (!NM_DEVICE_CLASS (nm_device_tun_parent_class)->connection_compatible (device, connection, error)) return FALSE; if (!nm_connection_is_type (connection, NM_SETTING_TUN_SETTING_NAME)) { g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, _("The connection was not a tun connection.")); return FALSE; } s_tun = nm_connection_get_setting_tun (connection); mode = tun_mode_from_string (priv->mode); if (s_tun && mode != nm_setting_tun_get_mode (s_tun)) { g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, _("The mode of the device and the connection didn't match")); return FALSE; } return TRUE; }
/** * nm_device_tun_get_group: * @device: a #NMDeviceTun * * Gets the tunnel group. * * Returns: the gid of the tunnel group, or -1 if it has no owner. * * Since: 1.2 **/ gint64 nm_device_tun_get_group (NMDeviceTun *device) { g_return_val_if_fail (NM_IS_DEVICE_TUN (device), -1); return NM_DEVICE_TUN_GET_PRIVATE (device)->group; }
/** * nm_device_tun_get_vnet_hdr: * @device: a #NMDeviceTun * * Returns whether the #NMDeviceTun has the IFF_VNET_HDR flag. * * Returns: %TRUE if the device has the flag, %FALSE otherwise * * Since: 1.2 **/ gboolean nm_device_tun_get_vnet_hdr (NMDeviceTun *device) { g_return_val_if_fail (NM_IS_DEVICE_TUN (device), FALSE); return NM_DEVICE_TUN_GET_PRIVATE (device)->vnet_hdr; }
static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NMDeviceTun *self = NM_DEVICE_TUN (object); NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); const char *str; switch (prop_id) { case PROP_MODE: /* construct-only */ str = g_value_get_string (value); /* mode is G_PARAM_STATIC_STRINGS */ if (g_strcmp0 (str, "tun") == 0) priv->mode = "tun"; else if (g_strcmp0 (str, "tap") == 0) priv->mode = "tap"; else g_return_if_fail (FALSE); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void reload_tun_properties (NMDeviceTun *self) { NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); GObject *object = G_OBJECT (self); NMPlatformTunProperties props; if (!nm_platform_tun_get_properties (NM_PLATFORM_GET, nm_device_get_ifindex (NM_DEVICE (self)), &props)) { _LOGD (LOGD_HW, "could not read tun properties"); return; } g_object_freeze_notify (object); if (priv->props.owner != props.owner) g_object_notify (object, NM_DEVICE_TUN_OWNER); if (priv->props.group != props.group) g_object_notify (object, NM_DEVICE_TUN_GROUP); if (priv->props.no_pi != props.no_pi) g_object_notify (object, NM_DEVICE_TUN_NO_PI); if (priv->props.vnet_hdr != props.vnet_hdr) g_object_notify (object, NM_DEVICE_TUN_VNET_HDR); if (priv->props.multi_queue != props.multi_queue) g_object_notify (object, NM_DEVICE_TUN_MULTI_QUEUE); memcpy (&priv->props, &props, sizeof (NMPlatformTunProperties)); g_object_thaw_notify (object); }
static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NMDeviceTun *self = NM_DEVICE_TUN (object); NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); switch (prop_id) { case PROP_OWNER: g_value_set_int64 (value, priv->props.owner); break; case PROP_GROUP: g_value_set_int64 (value, priv->props.group); break; case PROP_MODE: g_value_set_string (value, priv->mode); break; case PROP_NO_PI: g_value_set_boolean (value, priv->props.no_pi); break; case PROP_VNET_HDR: g_value_set_boolean (value, priv->props.vnet_hdr); break; case PROP_MULTI_QUEUE: g_value_set_boolean (value, priv->props.multi_queue); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
/** * nm_device_tun_get_hw_address: * @device: a #NMDeviceTun * * Gets the hardware (MAC) address of the #NMDeviceTun * * Returns: the hardware address. This is the internal string used by the * device, and must not be modified. * * Since: 1.2 **/ const char * nm_device_tun_get_hw_address (NMDeviceTun *device) { g_return_val_if_fail (NM_IS_DEVICE_TUN (device), NULL); return nm_str_not_empty (NM_DEVICE_TUN_GET_PRIVATE (device)->hw_address); }
static NMActStageReturn act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) { NMDeviceTun *self = NM_DEVICE_TUN (device); NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); NMSettingWired *s_wired; const char *cloned_mac; NMActStageReturn ret; g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); ret = NM_DEVICE_CLASS (nm_device_tun_parent_class)->act_stage1_prepare (device, reason); if (ret != NM_ACT_STAGE_RETURN_SUCCESS) return ret; /* Nothing to do for TUN devices */ if (g_strcmp0 (priv->mode, "tap")) return NM_ACT_STAGE_RETURN_SUCCESS; s_wired = (NMSettingWired *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_WIRED); if (s_wired) { /* Set device MAC address if the connection wants to change it */ cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); nm_device_set_hw_addr (device, cloned_mac, "set", LOGD_DEVICE); } return NM_ACT_STAGE_RETURN_SUCCESS; }
static void finalize (GObject *object) { NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (object); g_free (priv->mode); G_OBJECT_CLASS (nm_device_tun_parent_class)->finalize (object); }
static void unrealize_notify (NMDevice *device) { NMDeviceTun *self = NM_DEVICE_TUN (device); NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); GParamSpec **properties; guint n_properties, i; NM_DEVICE_CLASS (nm_device_tun_parent_class)->unrealize_notify (device); memset (&priv->props, 0, sizeof (NMPlatformTunProperties)); properties = g_object_class_list_properties (G_OBJECT_GET_CLASS (self), &n_properties); for (i = 0; i < n_properties; i++) g_object_notify_by_pspec (G_OBJECT (self), properties[i]); g_free (properties); }
static void reload_tun_properties (NMDeviceTun *self) { NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); GObject *object = G_OBJECT (self); NMPlatformTunProperties props; int ifindex; ifindex = nm_device_get_ifindex (NM_DEVICE (self)); if (ifindex > 0) { if (!nm_platform_link_tun_get_properties (NM_PLATFORM_GET, ifindex, &props)) { _LOGD (LOGD_DEVICE, "tun-properties: cannot loading tun properties from platform for ifindex %d", ifindex); ifindex = 0; } else if (g_strcmp0 (priv->mode, props.mode) != 0) { /* if the mode differs, we ignore what we loaded. A NMDeviceTun cannot * change the mode after construction. */ _LOGD (LOGD_DEVICE, "tun-properties: loading tun properties yielded tun-mode %s%s%s, but %s%s%s expected (ifindex %d)", NM_PRINT_FMT_QUOTE_STRING (props.mode), NM_PRINT_FMT_QUOTE_STRING (priv->mode), ifindex); ifindex = 0; } } else _LOGD (LOGD_DEVICE, "tun-properties: ignore loading properties due to missing ifindex"); if (ifindex <= 0) memset (&props, 0, sizeof (props)); g_object_freeze_notify (object); if (priv->props.owner != props.owner) g_object_notify (object, NM_DEVICE_TUN_OWNER); if (priv->props.group != props.group) g_object_notify (object, NM_DEVICE_TUN_GROUP); if (priv->props.no_pi != props.no_pi) g_object_notify (object, NM_DEVICE_TUN_NO_PI); if (priv->props.vnet_hdr != props.vnet_hdr) g_object_notify (object, NM_DEVICE_TUN_VNET_HDR); if (priv->props.multi_queue != props.multi_queue) g_object_notify (object, NM_DEVICE_TUN_MULTI_QUEUE); memcpy (&priv->props, &props, sizeof (NMPlatformTunProperties)); g_object_thaw_notify (object); }
static void setup (NMDevice *device, NMPlatformLink *plink) { NMDeviceTun *self = NM_DEVICE_TUN (device); NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); NM_DEVICE_CLASS (nm_device_tun_parent_class)->setup (device, plink); priv->mode = NULL; if (plink->type == NM_LINK_TYPE_TUN) priv->mode = "tun"; else if (plink->type == NM_LINK_TYPE_TAP) priv->mode = "tap"; else g_assert_not_reached (); g_object_notify (G_OBJECT (device), NM_DEVICE_TUN_MODE); reload_tun_properties (NM_DEVICE_TUN (device)); }
static void init_dbus (NMObject *object) { NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (object); const NMPropertiesInfo property_info[] = { { NM_DEVICE_TUN_HW_ADDRESS, &priv->hw_address }, { NM_DEVICE_TUN_MODE, &priv->mode }, { NM_DEVICE_TUN_OWNER, &priv->owner }, { NM_DEVICE_TUN_GROUP, &priv->group }, { NM_DEVICE_TUN_NO_PI, &priv->no_pi }, { NM_DEVICE_TUN_VNET_HDR, &priv->vnet_hdr }, { NM_DEVICE_TUN_MULTI_QUEUE, &priv->multi_queue }, { NULL }, }; NM_OBJECT_CLASS (nm_device_tun_parent_class)->init_dbus (object); _nm_object_register_properties (object, NM_DBUS_INTERFACE_DEVICE_TUN, property_info); }
static gboolean check_connection_compatible (NMDevice *device, NMConnection *connection) { NMDeviceTun *self = NM_DEVICE_TUN (device); NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); NMSettingTunMode mode; NMSettingTun *s_tun; gint64 user, group; if (!NM_DEVICE_CLASS (nm_device_tun_parent_class)->check_connection_compatible (device, connection)) return FALSE; s_tun = nm_connection_get_setting_tun (connection); if (!s_tun) return FALSE; if (nm_device_is_real (device)) { mode = tun_mode_from_string (priv->mode); if (mode != nm_setting_tun_get_mode (s_tun)) return FALSE; user = _nm_utils_ascii_str_to_int64 (nm_setting_tun_get_owner (s_tun), 10, 0, G_MAXINT32, -1); group = _nm_utils_ascii_str_to_int64 (nm_setting_tun_get_group (s_tun), 10, 0, G_MAXINT32, -1); if (user != priv->props.owner) return FALSE; if (group != priv->props.group) return FALSE; if (nm_setting_tun_get_pi (s_tun) == priv->props.no_pi) return FALSE; if (nm_setting_tun_get_vnet_hdr (s_tun) != priv->props.vnet_hdr) return FALSE; if (nm_setting_tun_get_multi_queue (s_tun) != priv->props.multi_queue) return FALSE; } return TRUE; }