コード例 #1
0
static NMDevice *
create_device (NMDeviceFactory *factory,
               const char *iface,
               const NMPlatformLink *plink,
               NMConnection *connection,
               gboolean *out_ignore)
{
	NMSettingIPTunnel *s_ip_tunnel;
	NMIPTunnelMode mode;
	NMLinkType link_type;

	if (connection) {
		s_ip_tunnel = nm_connection_get_setting_ip_tunnel (connection);
		mode = nm_setting_ip_tunnel_get_mode (s_ip_tunnel);
		link_type = tunnel_mode_to_link_type (mode);
	} else {
		link_type = plink->type;
		mode = platform_link_to_tunnel_mode (plink);
	}

	if (mode == NM_IP_TUNNEL_MODE_UNKNOWN)
		return NULL;

	return (NMDevice *) g_object_new (NM_TYPE_DEVICE_IP_TUNNEL,
	                                  NM_DEVICE_IFACE, iface,
	                                  NM_DEVICE_TYPE_DESC, "IPTunnel",
	                                  NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_IP_TUNNEL,
	                                  NM_DEVICE_LINK_TYPE, link_type,
	                                  NM_DEVICE_IP_TUNNEL_MODE, mode,
	                                  NULL);
}
コード例 #2
0
static gboolean
check_connection_compatible (NMDevice *device, NMConnection *connection)
{
	NMDeviceIPTunnel *self = NM_DEVICE_IP_TUNNEL (device);
	NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (self);
	NMSettingIPTunnel *s_ip_tunnel;
	const char *parent;

	if (!NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class)->check_connection_compatible (device, connection))
		return FALSE;

	s_ip_tunnel = nm_connection_get_setting_ip_tunnel (connection);
	if (!s_ip_tunnel)
		return FALSE;

	if (nm_setting_ip_tunnel_get_mode (s_ip_tunnel) != priv->mode)
		return FALSE;

	if (nm_device_is_real (device)) {
		/* Check parent interface; could be an interface name or a UUID */
		parent = nm_setting_ip_tunnel_get_parent (s_ip_tunnel);
		if (parent) {
			if (!match_parent (priv->parent, parent))
				return FALSE;
		}

		if (!address_equal_pp (priv->addr_family,
		                       nm_setting_ip_tunnel_get_local (s_ip_tunnel),
		                       priv->local))
			return FALSE;

		if (!address_equal_pp (priv->addr_family,
		                       nm_setting_ip_tunnel_get_remote (s_ip_tunnel),
		                       priv->remote))
			return FALSE;

		if (nm_setting_ip_tunnel_get_ttl (s_ip_tunnel) != priv->ttl)
			return FALSE;

		if (nm_setting_ip_tunnel_get_tos (s_ip_tunnel) != priv->tos)
			return FALSE;

		if (priv->addr_family == AF_INET) {
			if (nm_setting_ip_tunnel_get_path_mtu_discovery (s_ip_tunnel) != priv->path_mtu_discovery)
				return FALSE;
		} else {
			if (nm_setting_ip_tunnel_get_encapsulation_limit (s_ip_tunnel) != priv->encap_limit)
				return FALSE;

			if (nm_setting_ip_tunnel_get_flow_label (s_ip_tunnel) != priv->flow_label)
				return FALSE;
		}
	}

	return TRUE;
}
コード例 #3
0
static void
mode_changed (GObject    *object,
              GParamSpec *pspec,
              gpointer    user_data)
{
	NMSettingIPTunnel *s_ip_tunnel = NM_SETTING_IP_TUNNEL (object);
	NmtPageIPTunnel *ip_tunnel = NMT_PAGE_IP_TUNNEL (user_data);
	NmtPageIPTunnelPrivate *priv = NMT_PAGE_IP_TUNNEL_GET_PRIVATE (ip_tunnel);
	NMIPTunnelMode mode;
	gboolean enable_keys;

	mode = nm_setting_ip_tunnel_get_mode (s_ip_tunnel);
	enable_keys = NM_IN_SET (mode, NM_IP_TUNNEL_MODE_GRE, NM_IP_TUNNEL_MODE_IP6GRE);
	nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->input_key), enable_keys);
	nmt_newt_widget_set_visible (NMT_NEWT_WIDGET (priv->output_key), enable_keys);

	if (!enable_keys) {
		nmt_newt_entry_set_text (priv->input_key, "");
		nmt_newt_entry_set_text (priv->output_key, "");
	}
}
コード例 #4
0
static gboolean
create_and_realize (NMDevice *device,
                    NMConnection *connection,
                    NMDevice *parent,
                    const NMPlatformLink **out_plink,
                    GError **error)
{
	const char *iface = nm_device_get_iface (device);
	NMSettingIPTunnel *s_ip_tunnel;
	NMPlatformError plerr;
	NMPlatformLnkGre lnk_gre = { };
	NMPlatformLnkSit lnk_sit = { };
	NMPlatformLnkIpIp lnk_ipip = { };
	NMPlatformLnkIp6Tnl lnk_ip6tnl = { };
	const char *str;
	gint64 val;

	s_ip_tunnel = nm_connection_get_setting_ip_tunnel (connection);
	g_assert (s_ip_tunnel);

	switch (nm_setting_ip_tunnel_get_mode (s_ip_tunnel)) {
	case NM_IP_TUNNEL_MODE_GRE:
		if (parent)
			lnk_gre.parent_ifindex = nm_device_get_ifindex (parent);

		str = nm_setting_ip_tunnel_get_local (s_ip_tunnel);
		if (str)
			inet_pton (AF_INET, str, &lnk_gre.local);

		str = nm_setting_ip_tunnel_get_remote (s_ip_tunnel);
		g_assert (str);
		inet_pton (AF_INET, str, &lnk_gre.remote);

		lnk_gre.ttl = nm_setting_ip_tunnel_get_ttl (s_ip_tunnel);
		lnk_gre.tos = nm_setting_ip_tunnel_get_tos (s_ip_tunnel);
		lnk_gre.path_mtu_discovery = nm_setting_ip_tunnel_get_path_mtu_discovery (s_ip_tunnel);

		val = _nm_utils_ascii_str_to_int64 (nm_setting_ip_tunnel_get_input_key (s_ip_tunnel),
		                                    10,
		                                    0,
		                                    G_MAXUINT32,
		                                    -1);
		if (val != -1) {
			lnk_gre.input_key = val;
			lnk_gre.input_flags = NM_GRE_KEY;
		}

		val = _nm_utils_ascii_str_to_int64 (nm_setting_ip_tunnel_get_output_key (s_ip_tunnel),
		                                    10,
		                                    0,
		                                    G_MAXUINT32,
		                                    -1);
		if (val != -1) {
			lnk_gre.output_key = val;
			lnk_gre.output_flags = NM_GRE_KEY;
		}

		plerr = nm_platform_link_gre_add (NM_PLATFORM_GET, iface, &lnk_gre, out_plink);
		if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
			g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
			             "Failed to create GRE interface '%s' for '%s': %s",
			             iface,
			             nm_connection_get_id (connection),
			             nm_platform_error_to_string (plerr));
			return FALSE;
		}
		break;
	case NM_IP_TUNNEL_MODE_SIT:
		if (parent)
			lnk_sit.parent_ifindex = nm_device_get_ifindex (parent);

		str = nm_setting_ip_tunnel_get_local (s_ip_tunnel);
		if (str)
			inet_pton (AF_INET, str, &lnk_sit.local);

		str = nm_setting_ip_tunnel_get_remote (s_ip_tunnel);
		g_assert (str);
		inet_pton (AF_INET, str, &lnk_sit.remote);

		lnk_sit.ttl = nm_setting_ip_tunnel_get_ttl (s_ip_tunnel);
		lnk_sit.tos = nm_setting_ip_tunnel_get_tos (s_ip_tunnel);
		lnk_sit.path_mtu_discovery = nm_setting_ip_tunnel_get_path_mtu_discovery (s_ip_tunnel);

		plerr = nm_platform_link_sit_add (NM_PLATFORM_GET, iface, &lnk_sit, out_plink);
		if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
			g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
					"Failed to create SIT interface '%s' for '%s': %s",
					iface,
					nm_connection_get_id (connection),
					nm_platform_error_to_string (plerr));
			return FALSE;
		}
		break;
	case NM_IP_TUNNEL_MODE_IPIP:
		if (parent)
			lnk_ipip.parent_ifindex = nm_device_get_ifindex (parent);

		str = nm_setting_ip_tunnel_get_local (s_ip_tunnel);
		if (str)
			inet_pton (AF_INET, str, &lnk_ipip.local);

		str = nm_setting_ip_tunnel_get_remote (s_ip_tunnel);
		g_assert (str);
		inet_pton (AF_INET, str, &lnk_ipip.remote);

		lnk_ipip.ttl = nm_setting_ip_tunnel_get_ttl (s_ip_tunnel);
		lnk_ipip.tos = nm_setting_ip_tunnel_get_tos (s_ip_tunnel);
		lnk_ipip.path_mtu_discovery = nm_setting_ip_tunnel_get_path_mtu_discovery (s_ip_tunnel);

		plerr = nm_platform_link_ipip_add (NM_PLATFORM_GET, iface, &lnk_ipip, out_plink);
		if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
			g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
					"Failed to create IPIP interface '%s' for '%s': %s",
					iface,
					nm_connection_get_id (connection),
					nm_platform_error_to_string (plerr));
			return FALSE;
		}
		break;
	case NM_IP_TUNNEL_MODE_IPIP6:
	case NM_IP_TUNNEL_MODE_IP6IP6:
		if (parent)
			lnk_ip6tnl.parent_ifindex = nm_device_get_ifindex (parent);

		str = nm_setting_ip_tunnel_get_local (s_ip_tunnel);
		if (str)
			inet_pton (AF_INET6, str, &lnk_ip6tnl.local);

		str = nm_setting_ip_tunnel_get_remote (s_ip_tunnel);
		g_assert (str);
		inet_pton (AF_INET6, str, &lnk_ip6tnl.remote);

		lnk_ip6tnl.ttl = nm_setting_ip_tunnel_get_ttl (s_ip_tunnel);
		lnk_ip6tnl.tclass = nm_setting_ip_tunnel_get_tos (s_ip_tunnel);
		lnk_ip6tnl.encap_limit = nm_setting_ip_tunnel_get_encapsulation_limit (s_ip_tunnel);
		lnk_ip6tnl.flow_label = nm_setting_ip_tunnel_get_flow_label (s_ip_tunnel);
		lnk_ip6tnl.proto = nm_setting_ip_tunnel_get_mode (s_ip_tunnel) == NM_IP_TUNNEL_MODE_IPIP6 ? IPPROTO_IPIP : IPPROTO_IPV6;

		plerr = nm_platform_link_ip6tnl_add (NM_PLATFORM_GET, iface, &lnk_ip6tnl, out_plink);
		if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
			g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
			             "Failed to create IPIP interface '%s' for '%s': %s",
			             iface,
			             nm_connection_get_id (connection),
			             nm_platform_error_to_string (plerr));
			return FALSE;
		}
		break;
	default:
		g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
		             "Failed to create IP tunnel interface '%s' for '%s': mode %d not supported",
		             iface,
		             nm_connection_get_id (connection),
		             (int) nm_setting_ip_tunnel_get_mode (s_ip_tunnel));
		return FALSE;
	}

	return TRUE;
}
コード例 #5
0
static void
update_connection (NMDevice *device, NMConnection *connection)
{
	NMDeviceIPTunnel *self = NM_DEVICE_IP_TUNNEL (device);
	NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (self);
	NMSettingIPTunnel *s_ip_tunnel = nm_connection_get_setting_ip_tunnel (connection);
	NMDevice *parent = NULL;
	const char *setting_parent, *new_parent;

	if (!s_ip_tunnel) {
		s_ip_tunnel = (NMSettingIPTunnel *) nm_setting_ip_tunnel_new ();
		nm_connection_add_setting (connection, (NMSetting *) s_ip_tunnel);
	}

	if (nm_setting_ip_tunnel_get_mode (s_ip_tunnel) != priv->mode)
		g_object_set (G_OBJECT (s_ip_tunnel), NM_SETTING_IP_TUNNEL_MODE, priv->mode, NULL);

	if (priv->parent_ifindex > 0)
		parent = nm_manager_get_device_by_ifindex (nm_manager_get (), priv->parent_ifindex);

	/* Update parent in the connection; default to parent's interface name */
	if (parent) {
		new_parent = nm_device_get_iface (parent);
		setting_parent = nm_setting_ip_tunnel_get_parent (s_ip_tunnel);
		if (setting_parent && nm_utils_is_uuid (setting_parent)) {
			NMConnection *parent_connection;

			/* Don't change a parent specified by UUID if it's still valid */
			parent_connection = nm_connection_provider_get_connection_by_uuid (nm_connection_provider_get (),
			                                                                   setting_parent);
			if (parent_connection && nm_device_check_connection_compatible (parent, parent_connection))
				new_parent = NULL;
		}
		if (new_parent)
			g_object_set (s_ip_tunnel, NM_SETTING_IP_TUNNEL_PARENT, new_parent, NULL);
	} else
		g_object_set (s_ip_tunnel, NM_SETTING_IP_TUNNEL_PARENT, NULL, NULL);

	if (!address_equal_pp (priv->addr_family,
	                       nm_setting_ip_tunnel_get_local (s_ip_tunnel),
	                       priv->local))
		g_object_set (G_OBJECT (s_ip_tunnel), NM_SETTING_IP_TUNNEL_LOCAL, priv->local, NULL);

	if (!address_equal_pp (priv->addr_family,
	                       nm_setting_ip_tunnel_get_remote (s_ip_tunnel),
	                       priv->remote))
		g_object_set (G_OBJECT (s_ip_tunnel), NM_SETTING_IP_TUNNEL_REMOTE, priv->remote, NULL);

	if (nm_setting_ip_tunnel_get_ttl (s_ip_tunnel) != priv->ttl)
		g_object_set (G_OBJECT (s_ip_tunnel), NM_SETTING_IP_TUNNEL_TTL, priv->ttl, NULL);

	if (nm_setting_ip_tunnel_get_tos (s_ip_tunnel) != priv->tos)
		g_object_set (G_OBJECT (s_ip_tunnel), NM_SETTING_IP_TUNNEL_TOS, priv->tos, NULL);

	if (nm_setting_ip_tunnel_get_path_mtu_discovery (s_ip_tunnel) != priv->path_mtu_discovery) {
		g_object_set (G_OBJECT (s_ip_tunnel),
		              NM_SETTING_IP_TUNNEL_PATH_MTU_DISCOVERY,
		              priv->path_mtu_discovery,
		              NULL);
	}

	if (nm_setting_ip_tunnel_get_encapsulation_limit (s_ip_tunnel) != priv->encap_limit) {
		g_object_set (G_OBJECT (s_ip_tunnel),
		                        NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT,
		                        priv->encap_limit,
		                        NULL);
	}

	if (nm_setting_ip_tunnel_get_flow_label (s_ip_tunnel) != priv->flow_label) {
		g_object_set (G_OBJECT (s_ip_tunnel),
		                        NM_SETTING_IP_TUNNEL_FLOW_LABEL,
		                        priv->flow_label,
		                        NULL);
	}

	if (priv->mode == NM_IP_TUNNEL_MODE_GRE || priv->mode == NM_IP_TUNNEL_MODE_IP6GRE) {
		if (g_strcmp0 (nm_setting_ip_tunnel_get_input_key (s_ip_tunnel), priv->input_key)) {
			g_object_set (G_OBJECT (s_ip_tunnel),
			              NM_SETTING_IP_TUNNEL_INPUT_KEY,
			              priv->input_key,
			              NULL);
		}
		if (g_strcmp0 (nm_setting_ip_tunnel_get_output_key (s_ip_tunnel), priv->output_key)) {
			g_object_set (G_OBJECT (s_ip_tunnel),
			              NM_SETTING_IP_TUNNEL_OUTPUT_KEY,
			              priv->output_key,
			              NULL);
		}
	}
}
コード例 #6
0
static void
nmt_page_ip_tunnel_constructed (GObject *object)
{
	NmtPageIPTunnel *ip_tunnel = NMT_PAGE_IP_TUNNEL (object);
	NmtPageIPTunnelPrivate *priv = NMT_PAGE_IP_TUNNEL_GET_PRIVATE (ip_tunnel);
	NmtEditorSection *section;
	NmtEditorGrid *grid;
	NMSettingIPTunnel *s_ip_tunnel;
	NmtNewtWidget *widget, *parent;
	NMConnection *conn;
	GClosure *s2w, *w2s;

	conn = nmt_editor_page_get_connection (NMT_EDITOR_PAGE (ip_tunnel));
	s_ip_tunnel = nm_connection_get_setting_ip_tunnel (conn);
	if (!s_ip_tunnel) {
		nm_connection_add_setting (conn, nm_setting_ip_tunnel_new ());
		s_ip_tunnel = nm_connection_get_setting_ip_tunnel (conn);
	}

	/* Initialize the mode for new connections */
	if (nm_setting_ip_tunnel_get_mode (s_ip_tunnel) == NM_IP_TUNNEL_MODE_UNKNOWN) {
		g_object_set (s_ip_tunnel,
		              NM_SETTING_IP_TUNNEL_MODE, (guint) NM_IP_TUNNEL_MODE_IPIP,
		              NULL);
	}

	section = nmt_editor_section_new (_("IP tunnel"), NULL, TRUE);
	grid = nmt_editor_section_get_body (section);

	/* To convert between widget index (0-based) and setting index (1-based) */
	s2w = g_cclosure_new (G_CALLBACK (add_offset), GINT_TO_POINTER (-1), NULL);
	w2s = g_cclosure_new (G_CALLBACK (add_offset), GINT_TO_POINTER (1), NULL);

	widget = nmt_newt_popup_new (tunnel_mode);
	g_object_bind_property_with_closures (s_ip_tunnel, NM_SETTING_IP_TUNNEL_MODE,
	                        widget, "active",
	                        G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE,
	                        s2w, w2s);
	nmt_editor_grid_append (grid, _("Mode"), widget, NULL);

	widget = parent = nmt_device_entry_new (_("Parent"), 40, G_TYPE_NONE);
	g_object_bind_property (s_ip_tunnel, NM_SETTING_IP_TUNNEL_PARENT,
	                        widget, "interface-name",
	                        G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
	nmt_editor_grid_append (grid, NULL, widget, NULL);

	widget = nmt_newt_entry_new (40, 0);
	nmt_editor_grid_append (grid, _("Local IP"), widget, NULL);
	g_object_bind_property (s_ip_tunnel, NM_SETTING_IP_TUNNEL_LOCAL,
	                        widget, "text",
	                        G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);

	widget = nmt_newt_entry_new (40, 0);
	nmt_editor_grid_append (grid, _("Remote IP"), widget, NULL);
	g_object_bind_property (s_ip_tunnel, NM_SETTING_IP_TUNNEL_REMOTE,
	                        widget, "text",
	                        G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);

	widget = nmt_newt_entry_new (40, 0);
	nmt_editor_grid_append (grid, _("Input key"), widget, NULL);
	g_object_bind_property (s_ip_tunnel, NM_SETTING_IP_TUNNEL_INPUT_KEY,
	                        widget, "text",
	                        G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
	priv->input_key = NMT_NEWT_ENTRY (widget);

	widget = nmt_newt_entry_new (40, 0);
	nmt_editor_grid_append (grid, _("Output key"), widget, NULL);
	g_object_bind_property (s_ip_tunnel, NM_SETTING_IP_TUNNEL_OUTPUT_KEY,
	                        widget, "text",
	                        G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
	priv->output_key = NMT_NEWT_ENTRY (widget);

	widget = nmt_mtu_entry_new ();
	g_object_bind_property (s_ip_tunnel, NM_SETTING_IP_TUNNEL_MTU,
	                        widget, "mtu",
	                        G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
	nmt_editor_grid_append (grid, _("MTU"), widget, NULL);

	g_signal_connect (s_ip_tunnel, "notify::" NM_SETTING_IP_TUNNEL_MODE,
	                  G_CALLBACK (mode_changed), ip_tunnel);
	mode_changed (G_OBJECT (s_ip_tunnel), NULL, ip_tunnel);

	nmt_editor_page_add_section (NMT_EDITOR_PAGE (ip_tunnel), section);

	G_OBJECT_CLASS (nmt_page_ip_tunnel_parent_class)->constructed (object);
}