diff --git a/client-gtk/ni-client.c b/client-gtk/ni-client.c index fd3f68e..d49fb43 100644 --- a/client-gtk/ni-client.c +++ b/client-gtk/ni-client.c @@ -492,6 +492,25 @@ void ni_client_ask_change_iface_name (NIClient *ni_client, NIInterface *ni_inter send (ni_client->priv->client_socket, buffer, 7 + n_len, 0); } +void ni_client_ask_change_iface_mtu (NIClient *ni_client, NIInterface *ni_interface, guint new_mtu) { + unsigned char buffer[128]; + uint32_t index, mtu; + + if (ni_client->priv->client_socket < 0) { + return; + } + + index = ni_interface_get_index (ni_interface); + buffer[0] = NET_INADOR_TYPE_COMMAND; + buffer[1] = NET_INADOR_COMMAND_IFACE_CHANGE_MTU; + memcpy (&buffer[2], &index, 4); + //mtu = htonl (new_mtu); + mtu = new_mtu; + memcpy (&buffer[6], &mtu, 4); + + send (ni_client->priv->client_socket, buffer, 10, 0); +} + void ni_client_ask_ip_interface (NIClient *ni_client, NIInterface *ni_interface, int family) { unsigned char buffer[8]; uint32_t index; diff --git a/client-gtk/ni-client.h b/client-gtk/ni-client.h index 7b8d91e..18dcd06 100644 --- a/client-gtk/ni-client.h +++ b/client-gtk/ni-client.h @@ -81,6 +81,7 @@ void ni_client_ask_ips (NIClient *ni_client, NIInterface *ni_interface); void ni_client_ask_ip_new (NIClient *ni_client, NIInterface *ni_interface, int family, int prefix, struct_addr *addr, uint32_t flags, unsigned char scope, int has_local, struct_addr *local_addr, int has_brd, struct_addr *brd_addr); void ni_client_ask_ip_delete (NIClient *ni_client, NIInterface *ni_interface, NIIP *ni_ip); void ni_client_ask_change_iface_name (NIClient *ni_client, NIInterface *ni_interface, const gchar *new_name); +void ni_client_ask_change_iface_mtu (NIClient *ni_client, NIInterface *ni_interface, guint new_mtu); void ni_client_ask_up_down_interface (NIClient *ni_client, NIInterface *ni_interface, gboolean is_up); G_END_DECLS diff --git a/client-gtk/ni-interface.c b/client-gtk/ni-interface.c index b1ad066..6e3ac13 100644 --- a/client-gtk/ni-interface.c +++ b/client-gtk/ni-interface.c @@ -386,7 +386,7 @@ static void ni_interface_process_interface_update (NIInterface *ni_interface, gp } if (ni_interface->priv->mtu != mtu) { - ni_interface->priv->master_index = master_index; + ni_interface->priv->mtu = mtu; g_object_notify_by_pspec (G_OBJECT (ni_interface), obj_properties[PROP_MASTER_INDEX]); } @@ -602,6 +602,18 @@ guint ni_interface_get_flags (NIInterface *ni_interface) { return ni_interface->priv->flags; } +void ni_interface_set_mtu (NIInterface *ni_interface, guint mtu) { + g_return_if_fail (NI_IS_INTERFACE (ni_interface)); + + /* Enviar la petición al ni_client */ + ni_client_ask_change_iface_mtu (ni_interface->priv->ni_client, ni_interface, mtu); +} + +guint ni_interface_get_mtu (NIInterface *ni_interface) { + g_return_val_if_fail (NI_IS_INTERFACE (ni_interface), 0); + return ni_interface->priv->mtu; +} + void ni_interface_set_down (NIInterface *ni_interface) { g_return_if_fail (NI_IS_INTERFACE (ni_interface)); diff --git a/client-gtk/ni-interface.h b/client-gtk/ni-interface.h index 7c5ca8b..e9bbbd0 100644 --- a/client-gtk/ni-interface.h +++ b/client-gtk/ni-interface.h @@ -69,6 +69,8 @@ const gchar *ni_interface_get_name (NIInterface *ni_interface); void ni_interface_set_name (NIInterface *ni_interface, const gchar *name); guint ni_interface_get_iface_type (NIInterface *ni_interface); gboolean ni_interface_is_wireless (NIInterface *ni_interface); +guint ni_interface_get_mtu (NIInterface *ni_interface); +void ni_interface_set_mtu (NIInterface *ni_interface, guint mtu); NIClient *ni_interface_get_client (NIInterface *ni_interface); const GList *ni_interface_get_ip_list (NIInterface *ni_interface); guint ni_interface_get_flags (NIInterface *ni_interface); diff --git a/client-gtk/ni-window-interface.c b/client-gtk/ni-window-interface.c index ba8d9f1..6b90bef 100644 --- a/client-gtk/ni-window-interface.c +++ b/client-gtk/ni-window-interface.c @@ -44,8 +44,9 @@ struct _NIWindowInterfacePrivate { GtkWidget *vbox, *notebook; GtkWidget *vbox_ipv4, *vbox_ipv6, *vbox_info; - GtkWidget *info_name, *info_updown; + GtkWidget *info_name, *info_updown, *info_mtu; GtkWidget *button_name_apply, *button_name_revert; + GtkWidget *button_mtu_apply, *button_mtu_revert; GtkWidget *button_up, *button_down; GtkListStore *ipv4_store, *ipv6_store; GtkWidget *del_ipv4_button, *del_ipv6_button; @@ -69,6 +70,7 @@ enum { static void ni_window_interface_addr_added_cb (NIWindowInterface *window_iface, NIIP *ni_ip); void ni_window_interface_update_state_from_flags (NIWindowInterface *window_iface); static void ni_window_interface_name_cancel_cb (GtkWidget *widget, gpointer data); +static void ni_window_interface_mtu_cancel_cb (GtkWidget *widget, gpointer data); G_DEFINE_TYPE_WITH_PRIVATE (NIWindowInterface, ni_window_interface, GTK_TYPE_WINDOW) @@ -109,6 +111,7 @@ static GObject *ni_interface_constructor (GType type, guint n_construct_properti static gboolean ni_window_interface_delete_event (GtkWidget *widget, GdkEventAny *event) { /* Restaurar la caja original del nombre de la interfaz, si está cambiada */ ni_window_interface_name_cancel_cb (NULL, widget); + ni_window_interface_mtu_cancel_cb (NULL, widget); return gtk_widget_hide_on_delete (widget); } @@ -253,6 +256,50 @@ static void ni_window_interface_name_apply_cb (GtkWidget *widget, gpointer data) gtk_widget_set_sensitive (window_iface->priv->button_name_revert, FALSE); } +/* Eventos cuando cambian el mtu */ +static void ni_window_interface_mtu_edit_cb (GtkSpinButton *spin, gpointer data) { + NIWindowInterface *window_iface = (NIWindowInterface *) data; + guint original_mtu = ni_interface_get_mtu (window_iface->priv->ni_interface); + guint new_mtu = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (window_iface->priv->info_mtu)); + + if (new_mtu == 0) { + gtk_widget_set_sensitive (window_iface->priv->button_mtu_apply, FALSE); + gtk_widget_set_sensitive (window_iface->priv->button_mtu_revert, TRUE); + } else if (new_mtu == original_mtu) { + gtk_widget_set_sensitive (window_iface->priv->button_mtu_apply, FALSE); + gtk_widget_set_sensitive (window_iface->priv->button_mtu_revert, FALSE); + } else { + gtk_widget_set_sensitive (window_iface->priv->button_mtu_apply, TRUE); + gtk_widget_set_sensitive (window_iface->priv->button_mtu_revert, TRUE); + } +} + +static void ni_window_interface_mtu_cancel_cb (GtkWidget *widget, gpointer data) { + NIWindowInterface *window_iface = (NIWindowInterface *) data; + gtk_spin_button_set_value (GTK_SPIN_BUTTON (window_iface->priv->info_mtu), ni_interface_get_mtu (window_iface->priv->ni_interface)); + + gtk_widget_set_sensitive (window_iface->priv->button_mtu_apply, FALSE); + gtk_widget_set_sensitive (window_iface->priv->button_mtu_revert, FALSE); +} + +static void ni_window_interface_mtu_apply_cb (GtkWidget *widget, gpointer data) { + NIWindowInterface *window_iface = (NIWindowInterface *) data; + guint new_mtu; + + if (gtk_widget_get_sensitive (window_iface->priv->button_mtu_apply) == FALSE) { + return; + } + new_mtu = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (window_iface->priv->info_mtu)); + + ni_interface_set_mtu (window_iface->priv->ni_interface, new_mtu); + + /* TODO: Activar el ícono de "cargando" en el entry + gtk_entry_set_icon_from_gicon (GTK_ENTRY (window_iface->priv->info_name), GTK_ENTRY_ICON_SECONDARY, */ + gtk_widget_set_sensitive (window_iface->priv->button_mtu_apply, FALSE); + gtk_widget_set_sensitive (window_iface->priv->button_mtu_revert, FALSE); +} + + static void ni_window_interface_down_cb (GtkWidget *widget, gpointer data) { NIWindowInterface *window_iface = (NIWindowInterface *) data; @@ -408,7 +455,7 @@ static void ni_window_interface_constructed (GObject *obj) { g_signal_connect (window_iface->priv->ni_interface, "notify::flags", G_CALLBACK (ni_window_interface_changed_flags_cb), window_iface); gtk_entry_set_text (GTK_ENTRY (window_iface->priv->info_name), ni_interface_get_name (window_iface->priv->ni_interface)); - + gtk_spin_button_set_value (GTK_SPIN_BUTTON (window_iface->priv->info_mtu), ni_interface_get_mtu(window_iface->priv->ni_interface)); ni_window_interface_update_state_from_flags (window_iface); } @@ -563,6 +610,34 @@ static void ni_window_interface_init (NIWindowInterface *window_iface) { g_signal_connect (priv->info_name, "activate", G_CALLBACK (ni_window_interface_name_apply_cb), window_iface); gtk_box_pack_end (GTK_BOX (hbox), priv->info_name, TRUE, TRUE, 0); + /* La botonera del MTU */ + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5); + gtk_box_pack_start (GTK_BOX (priv->vbox_info), hbox, FALSE, FALSE, 0); + + label = gtk_label_new ("MTU:"); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + gtk_size_group_add_widget (size_l, label); + + + priv->button_mtu_revert = gtk_button_new_from_icon_name ("view-refresh", GTK_ICON_SIZE_BUTTON); + gtk_widget_set_sensitive (priv->button_mtu_revert, FALSE); + g_signal_connect (priv->button_mtu_revert, "clicked", G_CALLBACK (ni_window_interface_mtu_cancel_cb), window_iface); + gtk_box_pack_end (GTK_BOX (hbox), priv->button_mtu_revert, FALSE, FALSE, 0); + + priv->button_mtu_apply = gtk_button_new_from_icon_name ("document-save", GTK_ICON_SIZE_BUTTON); + gtk_widget_set_sensitive (priv->button_mtu_apply, FALSE); + g_signal_connect (priv->button_mtu_apply, "clicked", G_CALLBACK (ni_window_interface_mtu_apply_cb), window_iface); + gtk_box_pack_end (GTK_BOX (hbox), priv->button_mtu_apply, FALSE, FALSE, 0); + + /* TODO: Revisar el minimo y máximo del MTU */ + priv->info_mtu = gtk_spin_button_new_with_range (1200, 9000, 10); + gtk_spin_button_set_digits (GTK_SPIN_BUTTON (priv->info_mtu), 0); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->info_mtu), 0); + g_signal_connect (priv->info_mtu, "value-changed", G_CALLBACK (ni_window_interface_mtu_edit_cb), window_iface); + g_signal_connect (priv->info_mtu, "activate", G_CALLBACK (ni_window_interface_mtu_apply_cb), window_iface); + gtk_box_pack_end (GTK_BOX (hbox), priv->info_mtu, TRUE, TRUE, 0); + /* Las banderas de la intefaz */ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_pack_start (GTK_BOX (priv->vbox_info), hbox, FALSE, FALSE, 0); diff --git a/src/interfaces.c b/src/interfaces.c index f3c603d..2afd479 100644 --- a/src/interfaces.c +++ b/src/interfaces.c @@ -113,6 +113,7 @@ static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg, if (iface == NULL) { /* Crear esta interfaz */ iface = malloc (sizeof (Interface)); + iface->handle = handle; memset (iface, 0, sizeof (Interface)); handle->interfaces = g_list_append (handle->interfaces, iface); diff --git a/src/manager.c b/src/manager.c index 4c49f1f..235613e 100644 --- a/src/manager.c +++ b/src/manager.c @@ -336,6 +336,33 @@ void _manager_execute_iface_change_name (ManagerClientInfo *manager_client, unsi } } +void _manager_execute_iface_change_mtu (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { + Interface *iface; + int ret; + uint32_t new_mtu; + + if (buffer_len < 6) { + _manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_IFACE_CHANGE_MTU); + return; + } + + iface = _manager_fetch_interface (manager_client, &buffer[2], NET_INADOR_COMMAND_IFACE_CHANGE_NAME); + if (iface == NULL) return; + + memcpy (&new_mtu, &buffer[6], 4); + //new_mtu = ntohl (new_mtu); + + /* TODO: Revisar el máximo de MTU que se puede poner */ + ret = interfaces_change_mtu (manager_client->manager->handle, iface->index, new_mtu); + + if (ret == 0) { + /* OK */ + _manager_send_executed (manager_client); + } else { + _manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_IFACE_CHANGE_MTU); + } +} + void _manager_execute_clear_ips (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) { int family; Interface *iface; @@ -596,6 +623,9 @@ static gboolean _manager_client_data (GIOChannel *source, GIOCondition condition case NET_INADOR_COMMAND_IFACE_CHANGE_NAME: _manager_execute_iface_change_name (manager_client, buffer, bytes); break; + case NET_INADOR_COMMAND_IFACE_CHANGE_MTU: + _manager_execute_iface_change_mtu (manager_client, buffer, bytes); + break; case NET_INADOR_COMMAND_LIST_IP: _manager_send_list_ips (manager_client, buffer, bytes); break;