Agrego eliminación de rutas.
parent
a9afc75ba6
commit
fbef149d4f
|
@ -222,7 +222,7 @@ static void ni_client_process_interface_response (NIClient *ni_client, gpointer
|
|||
g_signal_emit (ni_client, signals[NEW_INTERFACE], 0, ni_interface);
|
||||
}
|
||||
|
||||
static NIRoute *_ni_client_search_route (GList *list_routes, sa_family_t family, uint8_t type, uint32_t table, void *dest, uint32_t prefix, uint32_t priority) {
|
||||
static NIRoute *_ni_client_search_route (GList *list_routes, sa_family_t family, uint8_t tos, uint32_t table, void *dest, uint32_t prefix, uint32_t priority) {
|
||||
GList *g;
|
||||
NIRoute *ni_route;
|
||||
int family_size = 0;
|
||||
|
@ -236,10 +236,10 @@ static NIRoute *_ni_client_search_route (GList *list_routes, sa_family_t family,
|
|||
for (g = list_routes; g != NULL; g = g->next) {
|
||||
ni_route = (NIRoute *) g->data;
|
||||
|
||||
if (ni_route_get_family(ni_route) != family) continue;
|
||||
if (ni_route_get_route_type(ni_route) != type) continue;
|
||||
if (ni_route_get_table(ni_route) != table) continue;
|
||||
if (ni_route_get_priority(ni_route) != priority) continue;
|
||||
if (ni_route_get_family (ni_route) != family) continue;
|
||||
if (ni_route_get_route_tos (ni_route) != tos) continue;
|
||||
if (ni_route_get_table (ni_route) != table) continue;
|
||||
if (ni_route_get_priority( ni_route) != priority) continue;
|
||||
|
||||
if (memcmp (ni_route_get_dest (ni_route), dest, family_size) == 0 && ni_route_get_prefix(ni_route) == prefix) {
|
||||
return ni_route;
|
||||
|
@ -335,7 +335,7 @@ static void ni_client_process_route_response (NIClient *ni_client, gpointer data
|
|||
static void ni_client_process_route_del_response (NIClient *ni_client, gpointer data, guint size) {
|
||||
unsigned char *buffer = (unsigned char *) data;
|
||||
uint8_t family, family_size;
|
||||
uint8_t type, prefix;
|
||||
uint8_t tos, prefix;
|
||||
uint32_t tabla, prioridad;
|
||||
NIRoute *ni_route;
|
||||
struct_addr dest;
|
||||
|
@ -351,7 +351,7 @@ static void ni_client_process_route_del_response (NIClient *ni_client, gpointer
|
|||
list_routes = ni_client->priv->routes_v6;
|
||||
}
|
||||
|
||||
type = buffer[3];
|
||||
tos = buffer[3];
|
||||
|
||||
memcpy (&tabla, &buffer[4], 4);
|
||||
prefix = buffer[8];
|
||||
|
@ -359,7 +359,7 @@ static void ni_client_process_route_del_response (NIClient *ni_client, gpointer
|
|||
|
||||
memcpy (&dest, &buffer[13], family_size);
|
||||
|
||||
ni_route = _ni_client_search_route (list_routes, family, type, tabla, &dest, prefix, prioridad);
|
||||
ni_route = _ni_client_search_route (list_routes, family, tos, tabla, &dest, prefix, prioridad);
|
||||
|
||||
if (ni_route == NULL) {
|
||||
/* ¿No hay ruta? Raro */
|
||||
|
@ -991,6 +991,45 @@ void ni_client_ask_route_new (NIClient *ni_client, int family, int prefix, struc
|
|||
send (ni_client->priv->client_socket, buffer, pos, 0);
|
||||
}
|
||||
|
||||
void ni_client_ask_route_del (NIClient *ni_client, NIRoute *route) {
|
||||
unsigned char buffer[80];
|
||||
int family_size, family;
|
||||
int pos, c;
|
||||
const struct_addr *dest;
|
||||
uint32_t tabla, priority;
|
||||
|
||||
if (ni_client->priv->client_socket < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
family = ni_route_get_family (route);
|
||||
|
||||
if (family == AF_INET) {
|
||||
family_size = sizeof (struct in_addr);
|
||||
} else if (family == AF_INET6) {
|
||||
family_size = sizeof (struct in6_addr);
|
||||
}
|
||||
|
||||
buffer[0] = NET_INADOR_TYPE_COMMAND;
|
||||
buffer[1] = NET_INADOR_COMMAND_REMOVE_ROUTE;
|
||||
buffer[2] = family;
|
||||
buffer[3] = ni_route_get_route_tos (route);
|
||||
|
||||
tabla = ni_route_get_table (route);
|
||||
memcpy (&buffer[4], &tabla, 4);
|
||||
|
||||
buffer[8] = ni_route_get_prefix (route);
|
||||
priority = ni_route_get_priority (route);
|
||||
memcpy (&buffer[9], &priority, 4);
|
||||
|
||||
dest = ni_route_get_dest (route);
|
||||
memcpy (&buffer[13], dest, family_size);
|
||||
|
||||
pos = 13 + family_size;
|
||||
|
||||
send (ni_client->priv->client_socket, buffer, pos, 0);
|
||||
}
|
||||
|
||||
static void ni_client_foreach_has_table (gpointer key, gpointer value, gpointer data) {
|
||||
GList **lista = (GList **) data;
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ struct _NIClient {
|
|||
};
|
||||
|
||||
typedef struct _NIInterface NIInterface;
|
||||
typedef struct _NIRoute NIRoute;
|
||||
|
||||
/*
|
||||
* Method definitions.
|
||||
|
@ -96,6 +97,7 @@ GList *ni_client_get_routes_v4 (NIClient *ni_client);
|
|||
GList *ni_client_get_routes_v6 (NIClient *ni_client);
|
||||
|
||||
void ni_client_ask_route_new (NIClient *ni_client, int family, int prefix, struct_addr *dest, int type, uint32_t tabla, int protocol, int tos, int scope, int has_prefsrc, struct_addr *prefsrc, uint32_t priority, GList *gws);
|
||||
void ni_client_ask_route_del (NIClient *ni_client, NIRoute *route);
|
||||
|
||||
void ni_client_ask_interface_clear_master (NIClient *ni_client, NIInterface *ni_interface);
|
||||
void ni_client_ask_interface_set_master (NIClient *ni_client, NIInterface *ni_interface, NIInterface *master);
|
||||
|
|
|
@ -241,7 +241,7 @@ static gboolean ni_route_process_route_response (NIClient *ni_client, unsigned c
|
|||
|
||||
/* Tengo suficientes datos, revisar si es mi ruta */
|
||||
if (ni_route->priv->family != family) return FALSE;
|
||||
if (ni_route->priv->type != type) return FALSE;
|
||||
if (ni_route->priv->tos != tos) return FALSE;
|
||||
if (ni_route->priv->table != tabla) return FALSE;
|
||||
if (ni_route->priv->priority != prioridad) return FALSE;
|
||||
|
||||
|
@ -351,6 +351,12 @@ guint ni_route_get_route_type (NIRoute *ni_route) {
|
|||
return ni_route->priv->type;
|
||||
}
|
||||
|
||||
guint ni_route_get_route_tos (NIRoute *ni_route) {
|
||||
g_return_val_if_fail (NI_IS_ROUTE (ni_route), 0);
|
||||
|
||||
return ni_route->priv->tos;
|
||||
}
|
||||
|
||||
guint ni_route_get_family (NIRoute *ni_route) {
|
||||
g_return_val_if_fail (NI_IS_ROUTE (ni_route), 0);
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ NIRoute *ni_route_new (NIClient *ni_client, int family, int type, uint32_t table
|
|||
NIClient *ni_route_get_client (NIRoute *ni_route);
|
||||
guint ni_route_get_family (NIRoute *ni_route);
|
||||
guint ni_route_get_route_type (NIRoute *ni_route);
|
||||
guint ni_route_get_route_tos (NIRoute *ni_route);
|
||||
const struct_addr *ni_route_get_dest (NIRoute *ni_route);
|
||||
guint ni_route_get_prefix (NIRoute *ni_route);
|
||||
uint32_t ni_route_get_table (NIRoute *ni_route);
|
||||
|
|
|
@ -150,6 +150,8 @@ static void ni_window_route_route_added_cb (NIWindowRoute *window_route, NIRoute
|
|||
struct _NIWindowRouteSearchTable for_search;
|
||||
int route_type;
|
||||
char *route_type_desc;
|
||||
int tos;
|
||||
char *route_tos_desc;
|
||||
|
||||
family = ni_route_get_family (ni_route);
|
||||
dest = ni_route_get_dest (ni_route);
|
||||
|
@ -157,6 +159,7 @@ static void ni_window_route_route_added_cb (NIWindowRoute *window_route, NIRoute
|
|||
prefix = ni_route_get_prefix (ni_route);
|
||||
table = ni_route_get_table (ni_route);
|
||||
priority = ni_route_get_priority (ni_route);
|
||||
tos = ni_route_get_route_tos (ni_route);
|
||||
|
||||
if (family != window_route->priv->family) {
|
||||
return;
|
||||
|
@ -193,12 +196,20 @@ static void ni_window_route_route_added_cb (NIWindowRoute *window_route, NIRoute
|
|||
} else {
|
||||
snprintf (buffer, sizeof (buffer), "%s/%i", buffer_ip, prefix);
|
||||
}
|
||||
|
||||
if (route_type_desc != NULL) {
|
||||
snprintf (buffer2, sizeof (buffer2), "%s %s", buffer, route_type_desc);
|
||||
} else {
|
||||
strncpy (buffer2, buffer, sizeof (buffer2));
|
||||
}
|
||||
|
||||
route_tos_desc = NULL;
|
||||
if (tos != 0) {
|
||||
snprintf (buffer, sizeof (buffer), "%s [TOS 0x%02x]", buffer2, tos);
|
||||
} else {
|
||||
strncpy (buffer, buffer2, sizeof (buffer));
|
||||
}
|
||||
|
||||
/* Preparar el pref-src, si lo tiene */
|
||||
buffer_ip[0] = 0;
|
||||
if (ni_route_has_prefsrc (ni_route)) {
|
||||
|
@ -218,7 +229,7 @@ static void ni_window_route_route_added_cb (NIWindowRoute *window_route, NIRoute
|
|||
gtk_list_store_insert_with_values (window_route->priv->tables_store, NULL, -1, TABLE_STORE_TABLE, table, TABLE_STORE_NAME, NULL, TABLE_STORE_IS_NEW, FALSE, -1);
|
||||
}
|
||||
|
||||
gtk_list_store_insert_with_values (window_route->priv->routes_store, NULL, -1, ROUTE_STORE_TABLE, table, ROUTE_STORE_COL_DST_GW, buffer2, ROUTE_STORE_COL_METRIC, priority, ROUTE_STORE_COL_PREFSRC, buffer_ip, ROUTE_STORE_COL_OBJECT, ni_route, -1);
|
||||
gtk_list_store_insert_with_values (window_route->priv->routes_store, NULL, -1, ROUTE_STORE_TABLE, table, ROUTE_STORE_COL_DST_GW, buffer, ROUTE_STORE_COL_METRIC, priority, ROUTE_STORE_COL_PREFSRC, buffer_ip, ROUTE_STORE_COL_OBJECT, ni_route, -1);
|
||||
|
||||
g_signal_connect (ni_route, "updated", G_CALLBACK (ni_window_route_updated_route_cb), window_route);
|
||||
}
|
||||
|
@ -459,6 +470,32 @@ static void ni_window_interface_delete_route_cb (NIClient *ni_client, NIRoute *n
|
|||
}
|
||||
}
|
||||
|
||||
static void has_route_selected_cb (GtkTreeSelection *selection, gpointer data) {
|
||||
NIWindowRoute *window_route = NI_WINDOW_ROUTE (data);
|
||||
|
||||
if (gtk_tree_selection_count_selected_rows (selection) > 0) {
|
||||
gtk_widget_set_sensitive (window_route->priv->del_route_button, TRUE);
|
||||
} else {
|
||||
gtk_widget_set_sensitive (window_route->priv->del_route_button, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void ni_window_route_del_route_button_add_cb (GtkWidget *button, gpointer data) {
|
||||
NIWindowRoute *window_route = NI_WINDOW_ROUTE (data);
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeSelection *selection;
|
||||
NIRoute *ni_route;
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window_route->priv->tree_routes));
|
||||
|
||||
gtk_tree_selection_get_selected (selection, &model, &iter);
|
||||
|
||||
gtk_tree_model_get (model, &iter, ROUTE_STORE_COL_OBJECT, &ni_route, -1);
|
||||
|
||||
ni_client_ask_route_del (window_route->priv->ni_client, ni_route);
|
||||
}
|
||||
|
||||
static void ni_window_route_add_route_button_add_cb (GtkWidget *button, gpointer data) {
|
||||
NIWindowRoute *window_route = NI_WINDOW_ROUTE (data);
|
||||
GtkWidget *dialog;
|
||||
|
@ -720,12 +757,12 @@ static void ni_window_route_init (NIWindowRoute *window_route) {
|
|||
|
||||
priv->del_route_button = gtk_button_new_from_icon_name ("list-remove", GTK_ICON_SIZE_LARGE_TOOLBAR);
|
||||
gtk_box_pack_start (GTK_BOX (vbox2), priv->del_route_button, FALSE, FALSE, 0);
|
||||
//g_signal_connect (priv->del_route_button, "clicked", G_CALLBACK (ni_window_interface_addr_v6_button_del_cb), window_iface);
|
||||
g_signal_connect (priv->del_route_button, "clicked", G_CALLBACK (ni_window_route_del_route_button_add_cb), window_route);
|
||||
gtk_widget_set_sensitive (priv->del_route_button, FALSE);
|
||||
|
||||
/* Conectar la señal de cambio de selección del tree view */
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_routes));
|
||||
//g_signal_connect (selection, "changed", G_CALLBACK (has_ip_selected_v6_cb), window_iface);
|
||||
g_signal_connect (selection, "changed", G_CALLBACK (has_route_selected_cb), window_route);
|
||||
|
||||
/* La botonera inferior */
|
||||
hbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
|
||||
|
|
10
src/common.h
10
src/common.h
|
@ -233,9 +233,9 @@ typedef struct _Route {
|
|||
uint32_t table;
|
||||
struct_addr dest;
|
||||
uint8_t prefix;
|
||||
uint8_t tos;
|
||||
|
||||
uint8_t protocol;
|
||||
uint8_t tos;
|
||||
uint8_t scope;
|
||||
|
||||
struct_addr prefsrc;
|
||||
|
@ -248,10 +248,18 @@ typedef struct _Route {
|
|||
int for_delete;
|
||||
} Route;
|
||||
|
||||
typedef struct _RouteTable {
|
||||
uint32_t table;
|
||||
char name[256];
|
||||
|
||||
int for_delete, was_new;
|
||||
} RouteTable;
|
||||
|
||||
struct _NetworkInadorHandle {
|
||||
GList *interfaces;
|
||||
GList *route_v4_tables;
|
||||
GList *route_v6_tables;
|
||||
GList *route_tables_names;
|
||||
|
||||
NetworkInadorManager *manager;
|
||||
|
||||
|
|
103
src/manager.c
103
src/manager.c
|
@ -1106,7 +1106,7 @@ void _manager_send_route_del (ManagerClientInfo *manager_client, Route *route) {
|
|||
family_size = sizeof (struct in6_addr);
|
||||
}
|
||||
buffer[2] = route->family;
|
||||
buffer[3] = route->type;
|
||||
buffer[3] = route->tos;
|
||||
memcpy (&buffer[4], &route->table, 4);
|
||||
buffer[8] = route->prefix;
|
||||
memcpy (&buffer[9], &route->priority, 4);
|
||||
|
@ -1275,6 +1275,102 @@ void _manager_execute_add_route (ManagerClientInfo *manager_client, unsigned cha
|
|||
}
|
||||
}
|
||||
|
||||
void _manager_execute_del_route (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) {
|
||||
Route route;
|
||||
int ret;
|
||||
int family_size, wanted_size, family;
|
||||
int g, rem, pos;
|
||||
|
||||
if (buffer_len < 13) {
|
||||
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_REMOVE_ROUTE);
|
||||
return;
|
||||
}
|
||||
|
||||
family = buffer[2];
|
||||
|
||||
if (family != AF_INET && family != AF_INET6) {
|
||||
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_FAMILY, NET_INADOR_COMMAND_REMOVE_ROUTE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (family == AF_INET) {
|
||||
family_size = sizeof (struct in_addr);
|
||||
} else if (family == AF_INET6) {
|
||||
family_size = sizeof (struct in6_addr);
|
||||
}
|
||||
|
||||
/* Ya puedo revisar el resto de la longitud */
|
||||
wanted_size = 13 + family_size;
|
||||
if (buffer_len < wanted_size) {
|
||||
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_REMOVE_ROUTE);
|
||||
return;
|
||||
}
|
||||
|
||||
memset (&route, 0, sizeof (route));
|
||||
|
||||
/* Ejecutar el parsing */
|
||||
route.family = family;
|
||||
route.tos = buffer[3];
|
||||
memcpy (&route.table, &buffer[4], 4);
|
||||
route.prefix = buffer[8];
|
||||
memcpy (&route.priority, &buffer[9], 4);
|
||||
|
||||
memcpy (&route.dest, &buffer[13], family_size);
|
||||
ret = routes_del (manager_client->manager->handle, &route);
|
||||
|
||||
if (ret == 0) {
|
||||
/* OK */
|
||||
_manager_send_executed (manager_client);
|
||||
} else {
|
||||
_manager_send_error (manager_client, NET_INADOR_ERROR_NOT_EXECUTED, NET_INADOR_COMMAND_REMOVE_ROUTE);
|
||||
}
|
||||
}
|
||||
|
||||
void _manager_send_route_table (ManagerClientInfo *manager_client, RouteTable *rtable, gboolean is_event) {
|
||||
unsigned char buffer[80];
|
||||
int name_len;
|
||||
|
||||
if (is_event) {
|
||||
buffer[0] = NET_INADOR_TYPE_EVENT;
|
||||
buffer[1] = NET_INADOR_EVENT_ROUTE_TABLE_ADDED;
|
||||
} else {
|
||||
buffer[0] = NET_INADOR_TYPE_RESPONSE;
|
||||
buffer[1] = NET_INADOR_RESPONSE_ROUTE_TABLE;
|
||||
}
|
||||
|
||||
memcpy (&buffer[2], &rtable->table, 4);
|
||||
|
||||
name_len = strlen (rtable->name);
|
||||
buffer[6] = name_len;
|
||||
memcpy (&buffer[7], rtable->name, name_len);
|
||||
|
||||
send (manager_client->fd, buffer, 7 + name_len, 0);
|
||||
}
|
||||
|
||||
void _manager_send_list_route_tables (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) {
|
||||
GList *g;
|
||||
RouteTable *rtable;
|
||||
uint32_t table;
|
||||
|
||||
if (buffer_len < 6) {
|
||||
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_LIST_ROUTE_TABLES);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy (&table, &buffer[2], 4);
|
||||
|
||||
for (g = manager_client->manager->handle->route_v4_tables; g != NULL; g = g->next) {
|
||||
rtable = (RouteTable *) g->data;
|
||||
|
||||
if (table != 0 && rtable->table != table) continue;
|
||||
|
||||
_manager_send_route_table (manager_client, rtable, FALSE);
|
||||
}
|
||||
|
||||
_manager_send_end_command (manager_client, NET_INADOR_COMMAND_LIST_ROUTE_TABLES);
|
||||
}
|
||||
|
||||
static gboolean _manager_client_data (GIOChannel *source, GIOCondition condition, gpointer data) {
|
||||
ManagerClientInfo *manager_client = (ManagerClientInfo *) data;
|
||||
NetworkInadorManager *manager = manager_client->manager;
|
||||
|
@ -1380,7 +1476,10 @@ static gboolean _manager_client_data (GIOChannel *source, GIOCondition condition
|
|||
_manager_execute_add_route (manager_client, buffer, bytes);
|
||||
break;
|
||||
case NET_INADOR_COMMAND_REMOVE_ROUTE:
|
||||
|
||||
_manager_execute_del_route (manager_client, buffer, bytes);
|
||||
break;
|
||||
case NET_INADOR_COMMAND_LIST_ROUTE_TABLES:
|
||||
_manager_send_list_route_tables (manager_client, buffer, bytes);
|
||||
break;
|
||||
default:
|
||||
_manager_send_error (manager_client, NET_INADOR_ERROR_WRONG_COMMAND, command);
|
||||
|
|
|
@ -44,6 +44,8 @@ enum {
|
|||
NET_INADOR_COMMAND_ADD_ROUTE,
|
||||
NET_INADOR_COMMAND_REMOVE_ROUTE,
|
||||
|
||||
NET_INADOR_COMMAND_LIST_ROUTE_TABLES = 72,
|
||||
|
||||
NET_INADOR_COMMAND_SET_EVENT_MASK = 192,
|
||||
|
||||
/* Los siguientes comandos son para uso interno */
|
||||
|
@ -72,6 +74,9 @@ enum {
|
|||
|
||||
NET_INADOR_EVENT_ROUTE_ADDED = 10,
|
||||
NET_INADOR_EVENT_ROUTE_REMOVED,
|
||||
|
||||
NET_INADOR_EVENT_ROUTE_TABLE_ADDED = 14,
|
||||
NET_INADOR_EVENT_ROUTE_TABLE_REMOVED,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -83,6 +88,8 @@ enum {
|
|||
NET_INADOR_RESPONSE_DHCP_STATUS = 6,
|
||||
|
||||
NET_INADOR_RESPONSE_ROUTE = 10,
|
||||
|
||||
NET_INADOR_RESPONSE_ROUTE_TABLE = 14
|
||||
};
|
||||
|
||||
enum {
|
||||
|
|
216
src/routes.c
216
src/routes.c
|
@ -26,6 +26,8 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
|
@ -75,7 +77,7 @@ int _route_same_list_nexthops (int family, GList *nexthops_a, GList *nexthops_b)
|
|||
return 0;
|
||||
}
|
||||
|
||||
Route *_route_search_route (GList *list_routes, sa_family_t family, uint8_t type, uint32_t table, void *dest, uint32_t prefix, uint32_t priority) {
|
||||
Route *_route_search_route (GList *list_routes, sa_family_t family, uint8_t tos, uint32_t table, void *dest, uint32_t prefix, uint32_t priority) {
|
||||
GList *g;
|
||||
Route *route;
|
||||
int family_size = 0;
|
||||
|
@ -90,8 +92,11 @@ Route *_route_search_route (GList *list_routes, sa_family_t family, uint8_t type
|
|||
route = (Route *) g->data;
|
||||
|
||||
if (route->family != family) continue;
|
||||
if (route->type != type) continue;
|
||||
|
||||
/* Por tos si genera diferencia */
|
||||
if (route->tos != tos) continue;
|
||||
if (route->table != table) continue;
|
||||
/* Por métrica */
|
||||
if (route->priority != priority) continue;
|
||||
|
||||
if (memcmp (&route->dest, dest, family_size) == 0 && route->prefix == prefix) {
|
||||
|
@ -158,7 +163,7 @@ int routes_receive_message_newroute (struct nl_msg *msg, void *arg) {
|
|||
int rtnhp_len;
|
||||
int multipath_len;
|
||||
unsigned char *p;
|
||||
uint8_t route_type;
|
||||
uint8_t route_type, tos;
|
||||
struct_addr dest;
|
||||
uint32_t priority = 0;
|
||||
int was_new = 0, was_update = 0;
|
||||
|
@ -183,7 +188,9 @@ int routes_receive_message_newroute (struct nl_msg *msg, void *arg) {
|
|||
route_list = handle->route_v6_tables;
|
||||
}
|
||||
|
||||
/* Recuperar el tipo de ruta */
|
||||
/* Recuperar el tos, porque marca diferencia entre rutas */
|
||||
tos = rtm_hdr->rtm_tos;
|
||||
|
||||
route_type = rtm_hdr->rtm_type;
|
||||
|
||||
/* Recuperar el prefijo */
|
||||
|
@ -217,7 +224,7 @@ int routes_receive_message_newroute (struct nl_msg *msg, void *arg) {
|
|||
}
|
||||
}
|
||||
/* TODO: Revisar si la ruta que procesamos ya existe */
|
||||
route = _route_search_route (route_list, family, route_type, table, &dest, prefix, priority);
|
||||
route = _route_search_route (route_list, family, tos, table, &dest, prefix, priority);
|
||||
|
||||
if (route == NULL) {
|
||||
/* Nueva ruta */
|
||||
|
@ -228,6 +235,7 @@ int routes_receive_message_newroute (struct nl_msg *msg, void *arg) {
|
|||
route->type = route_type;
|
||||
route->table = table;
|
||||
route->prefix = prefix;
|
||||
route->tos = tos;
|
||||
|
||||
route->priority = priority;
|
||||
route->for_delete = 0;
|
||||
|
@ -252,11 +260,6 @@ int routes_receive_message_newroute (struct nl_msg *msg, void *arg) {
|
|||
was_update = 1;
|
||||
}
|
||||
|
||||
if (route->tos != rtm_hdr->rtm_tos) {
|
||||
route->tos = rtm_hdr->rtm_tos;
|
||||
was_update = 1;
|
||||
}
|
||||
|
||||
if (route->scope != rtm_hdr->rtm_scope) {
|
||||
route->scope = rtm_hdr->rtm_scope;
|
||||
was_update = 1;
|
||||
|
@ -350,7 +353,7 @@ int routes_receive_message_delroute (struct nl_msg *msg, void *arg) {
|
|||
int family, family_size = 0;
|
||||
struct rtmsg *rtm_hdr;
|
||||
struct nlattr *attr;
|
||||
uint8_t route_type;
|
||||
uint8_t route_tos;
|
||||
struct_addr dest;
|
||||
uint32_t priority = 0;
|
||||
GList *route_list = NULL;
|
||||
|
@ -372,8 +375,8 @@ int routes_receive_message_delroute (struct nl_msg *msg, void *arg) {
|
|||
route_list = handle->route_v6_tables;
|
||||
}
|
||||
|
||||
/* Recuperar el tipo de ruta */
|
||||
route_type = rtm_hdr->rtm_type;
|
||||
/* Recuperar el tos de la ruta*/
|
||||
route_tos = rtm_hdr->rtm_tos;
|
||||
|
||||
/* Recuperar el prefijo */
|
||||
prefix = rtm_hdr->rtm_dst_len;
|
||||
|
@ -406,7 +409,7 @@ int routes_receive_message_delroute (struct nl_msg *msg, void *arg) {
|
|||
}
|
||||
}
|
||||
|
||||
route = _route_search_route (route_list, family, route_type, table, &dest, prefix, priority);
|
||||
route = _route_search_route (route_list, family, route_tos, table, &dest, prefix, priority);
|
||||
|
||||
if (route == NULL) {
|
||||
/* ¿Notificación de eliminar una ruta que no existe? Super raro */
|
||||
|
@ -591,7 +594,61 @@ int routes_del (NetworkInadorHandle *handle, Route *route) {
|
|||
RouteNH *nh;
|
||||
GList *g;
|
||||
|
||||
/* TODO: Pendiente escribir esto */
|
||||
memset (&route_hdr, 0, sizeof (route_hdr));
|
||||
|
||||
route_hdr.rtm_family = route->family;
|
||||
route_hdr.rtm_dst_len = route->prefix;
|
||||
route_hdr.rtm_tos = route->tos;
|
||||
route_hdr.rtm_table = route->table;
|
||||
|
||||
msg = nlmsg_alloc_simple (RTM_DELROUTE, NLM_F_REQUEST);
|
||||
ret = nlmsg_append (msg, &route_hdr, sizeof (route_hdr), NLMSG_ALIGNTO);
|
||||
|
||||
if (ret != 0) {
|
||||
nlmsg_free (msg);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (route->family == AF_INET) {
|
||||
family_size = sizeof (struct in_addr);
|
||||
} else if (route->family == AF_INET6) {
|
||||
family_size = sizeof (struct in6_addr);
|
||||
}
|
||||
|
||||
ret = nla_put (msg, RTA_DST, family_size, &route->dest);
|
||||
if (route->priority != 0) {
|
||||
ret |= nla_put (msg, RTA_PRIORITY, 4, &route->priority);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
nlmsg_free (msg);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
nl_complete_msg (handle->nl_sock_route, msg);
|
||||
|
||||
ret = nl_send (handle->nl_sock_route, msg);
|
||||
|
||||
nlmsg_free (msg);
|
||||
if (ret <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = 0;
|
||||
nl_socket_modify_cb (handle->nl_sock_route, NL_CB_VALID, NL_CB_CUSTOM, _route_wait_ack_or_error, &error);
|
||||
nl_socket_modify_cb (handle->nl_sock_route, NL_CB_INVALID, NL_CB_CUSTOM, _route_wait_ack_or_error, &error);
|
||||
nl_socket_modify_cb (handle->nl_sock_route, NL_CB_ACK, NL_CB_CUSTOM, _route_wait_ack_or_error, &error);
|
||||
nl_socket_modify_err_cb (handle->nl_sock_route, NL_CB_CUSTOM, _route_wait_error, &error);
|
||||
|
||||
ret = nl_recvmsgs_default (handle->nl_sock_route);
|
||||
|
||||
if (ret < 0 || error < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void routes_ask (NetworkInadorHandle *handle) {
|
||||
|
@ -674,9 +731,138 @@ void routes_ask (NetworkInadorHandle *handle) {
|
|||
}
|
||||
}
|
||||
|
||||
gint _routes_table_find_by_number (gconstpointer left, gconstpointer right) {
|
||||
RouteTable *a, *b;
|
||||
|
||||
a = (RouteTable *) left;
|
||||
b = (RouteTable *) right;
|
||||
|
||||
return a->table != b->table;
|
||||
}
|
||||
|
||||
void _routes_table_parse_file (NetworkInadorHandle *handle, FILE *fd) {
|
||||
GList *g;
|
||||
RouteTable *rtable, temp_table;
|
||||
char buffer[2048];
|
||||
|
||||
while (fgets (buffer, sizeof (buffer), fd), feof (fd) != 0) {
|
||||
sscanf (buffer, "%d %s", &(temp_table.table), temp_table.name);
|
||||
|
||||
g = g_list_find_custom (handle->route_tables_names, &temp_table, _routes_table_find_by_number);
|
||||
|
||||
if (g != NULL) {
|
||||
/* El número de tabla ya existe, marcar y actualizar el nombre */
|
||||
rtable = (RouteTable *) g->data;
|
||||
|
||||
rtable->for_delete = 0;
|
||||
rtable->was_new = 0;
|
||||
} else {
|
||||
/* No existe, crear nueva */
|
||||
rtable = (RouteTable *) g_malloc (sizeof (RouteTable));
|
||||
rtable->table = temp_table.table;
|
||||
rtable->for_delete = 0;
|
||||
rtable->was_new = 1;
|
||||
}
|
||||
/* En cualquier caso actualizar el nombre */
|
||||
strncpy (rtable->name, temp_table.name, sizeof (rtable->name));
|
||||
}
|
||||
}
|
||||
|
||||
void routes_tables_read (NetworkInadorHandle *handle, int do_notify) {
|
||||
FILE *fd;
|
||||
GList *g, *h;
|
||||
RouteTable *rtable;
|
||||
DIR *dir;
|
||||
struct dirent *direntry;
|
||||
int len;
|
||||
char buffer[4096];
|
||||
|
||||
g = handle->route_tables_names;
|
||||
while (g != NULL) {
|
||||
rtable = (RouteTable *) g->data;
|
||||
|
||||
rtable->for_delete = 1;
|
||||
rtable->was_new = 0;
|
||||
g = g->next;
|
||||
}
|
||||
|
||||
//g_list_free_full (handle->route_tables_names, g_free);
|
||||
//handle->route_tables_names = NULL;
|
||||
|
||||
/* Intentar abrir /etc/iproute2/rt_tables */
|
||||
fd = fopen ("/etc/iproute2/rt_tables", "r");
|
||||
if (fd != NULL) {
|
||||
_routes_table_parse_file (handle, fd);
|
||||
|
||||
fclose (fd);
|
||||
}
|
||||
|
||||
/* Ahora leer todo el directorio /etc/iproute2/rt_tables.d/ y buscar archivos *.conf */
|
||||
dir = opendir ("/etc/iproute2/rt_tables.d");
|
||||
if (dir != NULL) {
|
||||
|
||||
while (direntry = readdir (dir), direntry != NULL) {
|
||||
len = strlen (direntry->d_name);
|
||||
|
||||
/* Buscar por archivos que terminen en .conf */
|
||||
if (len > 5 && strcmp (&(direntry->d_name[len - 5]), ".conf") == 0) {
|
||||
/* Intentar abrir este archivo y parsearlo */
|
||||
snprintf (buffer, sizeof (buffer), "/etc/iproute2/rt_tables.d/%s", direntry->d_name);
|
||||
fd = fopen (buffer, "r");
|
||||
|
||||
if (fd != NULL) {
|
||||
_routes_table_parse_file (handle, fd);
|
||||
|
||||
fclose (fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir (dir);
|
||||
}
|
||||
|
||||
/* Ahora, todas las tablas que están marcadas para eliminar, eliminarlas */
|
||||
g = handle->route_tables_names;
|
||||
|
||||
while (g != NULL) {
|
||||
h = g->next;
|
||||
|
||||
rtable = (RouteTable *) g->data;
|
||||
|
||||
if (rtable->for_delete) {
|
||||
handle->route_tables_names = g_list_delete_link (handle->route_tables_names, g);
|
||||
|
||||
if (do_notify) {
|
||||
/* TODO: Notificar al manager que esta tabla fué eliminada */
|
||||
}
|
||||
|
||||
g_free (rtable);
|
||||
}
|
||||
|
||||
g = h;
|
||||
}
|
||||
|
||||
g = handle->route_tables_names;
|
||||
while (g != NULL) {
|
||||
rtable = (RouteTable *) g->data;
|
||||
|
||||
if (rtable->was_new) {
|
||||
if (do_notify) {
|
||||
/* TODO: Notificar al manager que esta tabla fué agregada */
|
||||
}
|
||||
rtable->was_new = 0;
|
||||
}
|
||||
|
||||
g = g->next;
|
||||
}
|
||||
}
|
||||
|
||||
void routes_init (NetworkInadorHandle *handle) {
|
||||
/* Si es la primera vez que nos llaman, descargar una primera lista de interfaces */
|
||||
routes_ask (handle);
|
||||
|
||||
/* Inicializar los nombres de las tablas de ruteo */
|
||||
routes_tables_read (handle, FALSE);
|
||||
}
|
||||
|
||||
void routes_clean_up (NetworkInadorHandle *handle) {
|
||||
|
|
|
@ -33,6 +33,7 @@ void routes_ask (NetworkInadorHandle *handle);
|
|||
int routes_receive_message_newroute (struct nl_msg *msg, void *arg);
|
||||
int routes_receive_message_delroute (struct nl_msg *msg, void *arg);
|
||||
int routes_add (NetworkInadorHandle *handle, Route *route);
|
||||
int routes_del (NetworkInadorHandle *handle, Route *route);
|
||||
|
||||
void route_ask_delayed_delroute (NetworkInadorHandle *handle);
|
||||
|
||||
|
|
Loading…
Reference in New Issue