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; }
static void update_connection (NMDevice *device, NMConnection *connection) { NMDeviceTun *self = NM_DEVICE_TUN (device); NMSettingTun *s_tun = nm_connection_get_setting_tun (connection); NMPlatformTunProperties props; NMSettingTunMode mode; gint64 user, group; char *str; if (!s_tun) { s_tun = (NMSettingTun *) nm_setting_tun_new (); nm_connection_add_setting (connection, (NMSetting *) s_tun); } if (!nm_platform_link_tun_get_properties (NM_PLATFORM_GET, nm_device_get_ifindex (device), &props)) { _LOGW (LOGD_HW, "failed to get TUN interface info while updating connection."); return; } mode = tun_mode_from_string (props.mode); if (mode != nm_setting_tun_get_mode (s_tun)) g_object_set (G_OBJECT (s_tun), NM_SETTING_TUN_MODE, mode, NULL); 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 (props.owner != user) { str = props.owner >= 0 ? g_strdup_printf ("%" G_GINT32_FORMAT, (gint32) props.owner) : NULL; g_object_set (G_OBJECT (s_tun), NM_SETTING_TUN_OWNER, str, NULL); g_free (str); } if (props.group != group) { str = props.group >= 0 ? g_strdup_printf ("%" G_GINT32_FORMAT, (gint32) props.group) : NULL; g_object_set (G_OBJECT (s_tun), NM_SETTING_TUN_GROUP, str, NULL); g_free (str); } if ((!props.no_pi) != nm_setting_tun_get_pi (s_tun)) g_object_set (G_OBJECT (s_tun), NM_SETTING_TUN_PI, !props.no_pi, NULL); if (props.vnet_hdr != nm_setting_tun_get_vnet_hdr (s_tun)) g_object_set (G_OBJECT (s_tun), NM_SETTING_TUN_VNET_HDR, props.vnet_hdr, NULL); if (props.multi_queue != nm_setting_tun_get_multi_queue (s_tun)) g_object_set (G_OBJECT (s_tun), NM_SETTING_TUN_MULTI_QUEUE, props.multi_queue, NULL); }
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; }