From 64ca4703fb888cce2b6e6f57a546e296d154d879 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Wed, 9 Nov 2016 16:39:11 +0100 Subject: editor: add support for IP tunnel connections --- src/connection-editor/Makefile.am | 3 + src/connection-editor/ce-page-ip-tunnel.ui | 246 +++++++++++++++++++++++ src/connection-editor/connection-helpers.c | 2 + src/connection-editor/nm-connection-editor.c | 4 + src/connection-editor/page-ip-tunnel.c | 288 +++++++++++++++++++++++++++ src/connection-editor/page-ip-tunnel.h | 60 ++++++ 6 files changed, 603 insertions(+) create mode 100644 src/connection-editor/ce-page-ip-tunnel.ui create mode 100644 src/connection-editor/page-ip-tunnel.c create mode 100644 src/connection-editor/page-ip-tunnel.h diff --git a/src/connection-editor/Makefile.am b/src/connection-editor/Makefile.am index b6f31a5e..69b012f1 100644 --- a/src/connection-editor/Makefile.am +++ b/src/connection-editor/Makefile.am @@ -38,6 +38,8 @@ nm_connection_editor_SOURCES = \ page-wifi-security.c \ page-infiniband.h \ page-infiniband.c \ + page-ip-tunnel.h \ + page-ip-tunnel.c \ page-ip4.h \ page-ip4.c \ page-ip6.h \ @@ -108,6 +110,7 @@ ui_DATA = \ ce-ip4-routes.ui \ ce-page-ip6.ui \ ce-ip6-routes.ui \ + ce-page-ip-tunnel.ui \ ce-page-dsl.ui \ ce-page-mobile.ui \ ce-page-bluetooth.ui \ diff --git a/src/connection-editor/ce-page-ip-tunnel.ui b/src/connection-editor/ce-page-ip-tunnel.ui new file mode 100644 index 00000000..a1255ac9 --- /dev/null +++ b/src/connection-editor/ce-page-ip-tunnel.ui @@ -0,0 +1,246 @@ + + + + + + 10000 + 1 + 10 + + + + + + + + + IPIP + + + GRE + + + SIT + + + ISATAP + + + VTI + + + IP6IP6 + + + IPIP6 + + + IP6GRE + + + VTI6 + + + + + True + False + 48 + 48 + 12 + 12 + True + 0 + vertical + 8 + 36 + + + True + False + Device name + + + 0 + 0 + + + + + True + True + + + 1 + 0 + + + + + True + False + start + False + Parent device + + + 0 + 1 + + + + + True + True + True + + + 1 + 1 + + + + + True + False + start + False + Mode + + + 0 + 2 + + + + + True + False + start + False + Local IP + + + 0 + 3 + + + + + True + False + start + Remote IP + + + 0 + 4 + + + + + True + False + start + Input key + + + 0 + 5 + + + + + True + False + start + Output key + + + 0 + 6 + + + + + True + False + mode_store + + + + 0 + + + + + 1 + 2 + + + + + True + True + + + 1 + 3 + + + + + True + True + + + 1 + 4 + + + + + True + True + + + 1 + 5 + + + + + True + True + + + 1 + 6 + + + + + True + True + adjustment1 + 1 + + + 1 + 7 + + + + + True + False + start + MTU + + + 0 + 7 + + + + diff --git a/src/connection-editor/connection-helpers.c b/src/connection-editor/connection-helpers.c index e8cc6159..5fc9c6a3 100644 --- a/src/connection-editor/connection-helpers.c +++ b/src/connection-editor/connection-helpers.c @@ -30,6 +30,7 @@ #include "page-bluetooth.h" #include "page-dsl.h" #include "page-infiniband.h" +#include "page-ip-tunnel.h" #include "page-bond.h" #include "page-team.h" #include "page-bridge.h" @@ -116,6 +117,7 @@ get_connection_type_list (void) add_type_data_virtual (array, _("Team"), team_connection_new, NM_TYPE_SETTING_TEAM); add_type_data_virtual (array, _("Bridge"), bridge_connection_new, NM_TYPE_SETTING_BRIDGE); add_type_data_virtual (array, _("VLAN"), vlan_connection_new, NM_TYPE_SETTING_VLAN); + add_type_data_virtual (array, _("IP tunnel"), ip_tunnel_connection_new, NM_TYPE_SETTING_IP_TUNNEL); add_type_data_virtual (array, _("VPN"), vpn_connection_new, NM_TYPE_SETTING_VPN); diff --git a/src/connection-editor/nm-connection-editor.c b/src/connection-editor/nm-connection-editor.c index 45a95b09..24d4571e 100644 --- a/src/connection-editor/nm-connection-editor.c +++ b/src/connection-editor/nm-connection-editor.c @@ -40,6 +40,7 @@ #include "page-wifi-security.h" #include "page-ip4.h" #include "page-ip6.h" +#include "page-ip-tunnel.h" #include "page-dsl.h" #include "page-mobile.h" #include "page-bluetooth.h" @@ -776,6 +777,9 @@ nm_connection_editor_set_connection (NMConnectionEditor *editor, } else if (!strcmp (connection_type, NM_SETTING_VPN_SETTING_NAME)) { if (!add_page (editor, ce_page_vpn_new, editor->connection, error)) goto out; + } else if (!strcmp (connection_type, NM_SETTING_IP_TUNNEL_SETTING_NAME)) { + if (!add_page (editor, ce_page_ip_tunnel_new, editor->connection, error)) + goto out; } else if (!strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME)) { if (!add_page (editor, ce_page_dsl_new, editor->connection, error)) goto out; diff --git a/src/connection-editor/page-ip-tunnel.c b/src/connection-editor/page-ip-tunnel.c new file mode 100644 index 00000000..e131a6ec --- /dev/null +++ b/src/connection-editor/page-ip-tunnel.c @@ -0,0 +1,288 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Connection editor -- Connection editor for NetworkManager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2016 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include "page-ip-tunnel.h" + +#include + +#include "nm-connection-editor.h" + +G_DEFINE_TYPE (CEPageIPTunnel, ce_page_ip_tunnel, CE_TYPE_PAGE) + +#define CE_PAGE_IP_TUNNEL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CE_TYPE_PAGE_IP_TUNNEL, CEPageIPTunnelPrivate)) + +typedef struct { + NMSettingIPTunnel *setting; + + GtkEntry *name; + GtkEntry *parent; + GtkComboBox *mode; + GtkEntry *local; + GtkEntry *remote; + GtkEntry *input_key; + GtkEntry *output_key; + GtkSpinButton *mtu; +} CEPageIPTunnelPrivate; + +static void +ip_tunnel_private_init (CEPageIPTunnel *self) +{ + CEPageIPTunnelPrivate *priv = CE_PAGE_IP_TUNNEL_GET_PRIVATE (self); + GtkBuilder *builder; + + builder = CE_PAGE (self)->builder; + + priv->name = GTK_ENTRY (gtk_builder_get_object (builder, "ip_tunnel_name")); + priv->parent = GTK_ENTRY (gtk_builder_get_object (builder, "ip_tunnel_parent")); + priv->mode = GTK_COMBO_BOX (gtk_builder_get_object (builder, "ip_tunnel_mode")); + priv->local = GTK_ENTRY (gtk_builder_get_object (builder, "ip_tunnel_local")); + priv->remote = GTK_ENTRY (gtk_builder_get_object (builder, "ip_tunnel_remote")); + priv->input_key = GTK_ENTRY (gtk_builder_get_object (builder, "ip_tunnel_ikey")); + priv->output_key = GTK_ENTRY (gtk_builder_get_object (builder, "ip_tunnel_okey")); + priv->mtu = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "ip_tunnel_mtu")); +} + +static void +mode_changed (GtkComboBox *combo, gpointer user_data) +{ + CEPageIPTunnel *self = user_data; + CEPageIPTunnelPrivate *priv = CE_PAGE_IP_TUNNEL_GET_PRIVATE (self); + NMIPTunnelMode mode; + gboolean enable; + + mode = gtk_combo_box_get_active (combo) + 1; + + enable = (mode == NM_IP_TUNNEL_MODE_GRE || mode == NM_IP_TUNNEL_MODE_IP6GRE); + + gtk_widget_set_sensitive (GTK_WIDGET (priv->input_key), enable); + gtk_widget_set_sensitive (GTK_WIDGET (priv->output_key), enable); + + if (!enable) { + gtk_entry_set_text (priv->input_key, ""); + gtk_entry_set_text (priv->output_key, ""); + } +} + +static void +populate_ui (CEPageIPTunnel *self, NMConnection *connection) +{ + CEPageIPTunnelPrivate *priv = CE_PAGE_IP_TUNNEL_GET_PRIVATE (self); + NMSettingIPTunnel *setting = priv->setting; + NMIPTunnelMode mode; + const char *str; + int mtu_def; + + str = nm_connection_get_interface_name (CE_PAGE (self)->connection); + if (str) + gtk_entry_set_text (priv->name, str); + + str = nm_setting_ip_tunnel_get_parent (setting); + if (str) + gtk_entry_set_text (priv->parent, str); + + mode = nm_setting_ip_tunnel_get_mode (setting); + if (mode >= NM_IP_TUNNEL_MODE_IPIP && mode <= NM_IP_TUNNEL_MODE_VTI6) + gtk_combo_box_set_active (priv->mode, mode - 1); + + str = nm_setting_ip_tunnel_get_local (setting); + if (str) + gtk_entry_set_text (priv->local, str); + + str = nm_setting_ip_tunnel_get_remote (setting); + if (str) + gtk_entry_set_text (priv->remote, str); + + str = nm_setting_ip_tunnel_get_input_key (setting); + if (str) + gtk_entry_set_text (priv->input_key, str); + + str = nm_setting_ip_tunnel_get_output_key (setting); + if (str) + gtk_entry_set_text (priv->output_key, str); + + mtu_def = ce_get_property_default (NM_SETTING (setting), NM_SETTING_IP_TUNNEL_MTU); + ce_spin_automatic_val (priv->mtu, mtu_def); + + gtk_spin_button_set_value (priv->mtu, (gdouble) nm_setting_ip_tunnel_get_mtu (setting)); + + mode_changed (priv->mode, self); +} + +static void +stuff_changed (GtkEditable *editable, gpointer user_data) +{ + ce_page_changed (CE_PAGE (user_data)); +} + +static void +finish_setup (CEPageIPTunnel *self, gpointer unused, GError *error, gpointer user_data) +{ + CEPage *parent = CE_PAGE (self); + CEPageIPTunnelPrivate *priv = CE_PAGE_IP_TUNNEL_GET_PRIVATE (self); + + if (error) + return; + + populate_ui (self, parent->connection); + + g_signal_connect (priv->name, "changed", G_CALLBACK (stuff_changed), self); + g_signal_connect (priv->parent, "changed", G_CALLBACK (stuff_changed), self); + g_signal_connect (priv->mode, "changed", G_CALLBACK (stuff_changed), self); + g_signal_connect (priv->local, "changed", G_CALLBACK (stuff_changed), self); + g_signal_connect (priv->remote, "changed", G_CALLBACK (stuff_changed), self); + g_signal_connect (priv->input_key, "changed", G_CALLBACK (stuff_changed), self); + g_signal_connect (priv->output_key, "changed", G_CALLBACK (stuff_changed), self); + g_signal_connect (priv->mtu, "value-changed", G_CALLBACK (stuff_changed), self); + + g_signal_connect (priv->mode, "changed", G_CALLBACK (mode_changed), self); +} + +CEPage * +ce_page_ip_tunnel_new (NMConnectionEditor *editor, + NMConnection *connection, + GtkWindow *parent_window, + NMClient *client, + const char **out_secrets_setting_name, + GError **error) +{ + CEPageIPTunnel *self; + CEPageIPTunnelPrivate *priv; + + self = CE_PAGE_IP_TUNNEL (ce_page_new (CE_TYPE_PAGE_IP_TUNNEL, + editor, + connection, + parent_window, + client, + UIDIR "/ce-page-ip-tunnel.ui", + "IPTunnelPage", + _("IP tunnel"))); + if (!self) { + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("Could not load IP tunnel user interface.")); + return NULL; + } + + ip_tunnel_private_init (self); + priv = CE_PAGE_IP_TUNNEL_GET_PRIVATE (self); + + priv->setting = nm_connection_get_setting_ip_tunnel (connection); + if (!priv->setting) { + priv->setting = NM_SETTING_IP_TUNNEL (nm_setting_ip_tunnel_new ()); + nm_connection_add_setting (connection, NM_SETTING (priv->setting)); + } + + g_signal_connect (self, "initialized", G_CALLBACK (finish_setup), NULL); + + *out_secrets_setting_name = NM_SETTING_IP_TUNNEL_SETTING_NAME; + + return CE_PAGE (self); +} + +static void +ui_to_setting (CEPageIPTunnel *self) +{ + CEPageIPTunnelPrivate *priv = CE_PAGE_IP_TUNNEL_GET_PRIVATE (self); + const char *device; + const char *local; + const char *remote; + const char *input_key; + const char *output_key; + NMIPTunnelMode mode; + + device = gtk_entry_get_text (priv->parent); + if (device && !device[0]) + device = NULL; + + mode = gtk_combo_box_get_active (priv->mode) + 1; + + local = gtk_entry_get_text (priv->local); + if (local && !local[0]) + local = NULL; + + remote = gtk_entry_get_text (priv->remote); + if (remote && !remote[0]) + remote = NULL; + + input_key = gtk_entry_get_text (priv->input_key); + if (input_key && !input_key[0]) + input_key = NULL; + + + output_key = gtk_entry_get_text (priv->output_key); + if (output_key && !output_key[0]) + output_key = NULL; + + g_object_set (priv->setting, + NM_SETTING_IP_TUNNEL_PARENT, device, + NM_SETTING_IP_TUNNEL_MODE, mode, + NM_SETTING_IP_TUNNEL_LOCAL, local, + NM_SETTING_IP_TUNNEL_REMOTE, remote, + NM_SETTING_IP_TUNNEL_INPUT_KEY, input_key, + NM_SETTING_IP_TUNNEL_OUTPUT_KEY, output_key, + NM_SETTING_IP_TUNNEL_MTU, gtk_spin_button_get_value_as_int (priv->mtu), + NULL); +} + +static gboolean +ce_page_validate_v (CEPage *page, NMConnection *connection, GError **error) +{ + CEPageIPTunnel *self = CE_PAGE_IP_TUNNEL (page); + CEPageIPTunnelPrivate *priv = CE_PAGE_IP_TUNNEL_GET_PRIVATE (self); + + ui_to_setting (self); + return nm_setting_verify (NM_SETTING (priv->setting), connection, error); +} + +static void +ce_page_ip_tunnel_init (CEPageIPTunnel *self) +{ +} + +static void +ce_page_ip_tunnel_class_init (CEPageIPTunnelClass *ip_tunnel_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (ip_tunnel_class); + CEPageClass *parent_class = CE_PAGE_CLASS (ip_tunnel_class); + + g_type_class_add_private (object_class, sizeof (CEPageIPTunnelPrivate)); + + parent_class->ce_page_validate_v = ce_page_validate_v; +} + +void +ip_tunnel_connection_new (GtkWindow *parent, + const char *detail, + gpointer detail_data, + NMClient *client, + PageNewConnectionResultFunc result_func, + gpointer user_data) +{ + NMConnection *connection; + + connection = ce_page_new_connection (_("IP tunnel connection %d"), + NM_SETTING_IP_TUNNEL_SETTING_NAME, + FALSE, + client, + user_data); + nm_connection_add_setting (connection, nm_setting_ip_tunnel_new ()); + (*result_func) (connection, FALSE, NULL, user_data); +} + diff --git a/src/connection-editor/page-ip-tunnel.h b/src/connection-editor/page-ip-tunnel.h new file mode 100644 index 00000000..e2bef819 --- /dev/null +++ b/src/connection-editor/page-ip-tunnel.h @@ -0,0 +1,60 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Connection editor -- Connection editor for NetworkManager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2016 Red Hat, Inc. + */ + +#ifndef __PAGE_IP_TUNNEL_H__ +#define __PAGE_IP_TUNNEL_H__ + +#include +#include + +#include "ce-page.h" + +#define CE_TYPE_PAGE_IP_TUNNEL (ce_page_ip_tunnel_get_type ()) +#define CE_PAGE_IP_TUNNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CE_TYPE_PAGE_IP_TUNNEL, CEPageIPTunnel)) +#define CE_PAGE_IP_TUNNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CE_TYPE_PAGE_IP_TUNNEL, CEPageIPTunnelClass)) +#define CE_IS_PAGE_IP_TUNNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CE_TYPE_PAGE_IP_TUNNEL)) +#define CE_IS_PAGE_IP_TUNNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CE_TYPE_PAGE_IP_TUNNEL)) +#define CE_PAGE_IP_TUNNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CE_TYPE_PAGE_IP_TUNNEL, CEPageIPTunnelClass)) + +typedef struct { + CEPage parent; +} CEPageIPTunnel; + +typedef struct { + CEPageClass parent; +} CEPageIPTunnelClass; + +GType ce_page_ip_tunnel_get_type (void); + +CEPage *ce_page_ip_tunnel_new (NMConnectionEditor *editor, + NMConnection *connection, + GtkWindow *parent, + NMClient *client, + const char **out_secrets_setting_name, + GError **error); + +void ip_tunnel_connection_new (GtkWindow *parent, + const char *detail, + gpointer detail_data, + NMClient *client, + PageNewConnectionResultFunc callback, + gpointer user_data); + +#endif /* __PAGE_IP_TUNNEL_H__ */ -- cgit v1.2.1