Reactivo los nombre de tablas de ruteo y sus eventos en el manager.

master
Félix Arreola Rodríguez 2025-01-13 23:43:08 -06:00
parent 840b20a768
commit 0cfdfd21e3
19 changed files with 530 additions and 151 deletions

View File

@ -11,6 +11,7 @@ libnetworkinador_la_SOURCES = network-inador-public.h \
interfaces.c interfaces.h \ interfaces.c interfaces.h \
ip-address.c ip-address.h \ ip-address.c ip-address.h \
routes.c routes.h \ routes.c routes.h \
rtables.c rtables.h \
launch_process.c launch_process.h \ launch_process.c launch_process.h \
dhcp_client.c dhcp_client.h dhcpc_defs.h \ dhcp_client.c dhcp_client.h dhcpc_defs.h \
wireless_if.c wireless_if.h \ wireless_if.c wireless_if.h \

View File

@ -80,6 +80,16 @@ void network_manager_add_watch_route_deleted (NetworkInadorHandle *handle, Netwo
handle->notify_list.route_del_event_data = data; handle->notify_list.route_del_event_data = data;
} }
void network_manager_add_watch_route_table_added (NetworkInadorHandle *handle, NetworkInadorRouteTableAddEventCB cb, void *data) {
handle->notify_list.route_table_add_event_cb = cb;
handle->notify_list.route_table_add_event_data = data;
}
void network_manager_add_watch_route_table_deleted (NetworkInadorHandle *handle, NetworkInadorRouteTableDelEventCB cb, void *data) {
handle->notify_list.route_table_del_event_cb = cb;
handle->notify_list.route_table_del_event_data = data;
}
/* Disparar las vigilancias */ /* Disparar las vigilancias */
void network_manager_trigger_dhcp_event (NetworkInadorHandle *handle, InterfaceDHCPClientInfo *dhcpc) { void network_manager_trigger_dhcp_event (NetworkInadorHandle *handle, InterfaceDHCPClientInfo *dhcpc) {
Interface *iface = container_of (dhcpc, Interface, dhcpc); Interface *iface = container_of (dhcpc, Interface, dhcpc);
@ -140,3 +150,16 @@ void network_manager_trigger_route_deleted_event (NetworkInadorHandle *handle, R
} }
} }
/* Trggers de tablasde ruteo */
void network_manager_trigger_route_table_added_event (NetworkInadorHandle *handle, uint32_t table_index, const char *table_name) {
if (handle->notify_list.route_table_add_event_cb != NULL) {
handle->notify_list.route_table_add_event_cb (handle, table_index, table_name, handle->notify_list.route_table_add_event_data);
}
}
void network_manager_trigger_route_table_deleted_event (NetworkInadorHandle *handle, uint32_t table_index) {
if (handle->notify_list.route_table_del_event_cb != NULL) {
handle->notify_list.route_table_del_event_cb (handle, table_index, handle->notify_list.route_table_del_event_data);
}
}

View File

@ -36,6 +36,8 @@ void network_manager_trigger_ip_deleted_event (NetworkInadorHandle *handle, IPAd
void network_manager_trigger_route_added_event (NetworkInadorHandle *handle, Route *route); void network_manager_trigger_route_added_event (NetworkInadorHandle *handle, Route *route);
void network_manager_trigger_route_updated_event (NetworkInadorHandle *handle, Route *route); void network_manager_trigger_route_updated_event (NetworkInadorHandle *handle, Route *route);
void network_manager_trigger_route_deleted_event (NetworkInadorHandle *handle, Route *route); void network_manager_trigger_route_deleted_event (NetworkInadorHandle *handle, Route *route);
void network_manager_trigger_route_table_added_event (NetworkInadorHandle *handle, uint32_t table_index, const char *table_name);
void network_manager_trigger_route_table_deleted_event (NetworkInadorHandle *handle, uint32_t table_index);
#endif /* __EVENT_NOTIFY_H__ */ #endif /* __EVENT_NOTIFY_H__ */

View File

@ -32,10 +32,18 @@
#include "network-inador-private.h" #include "network-inador-private.h"
static void network_inador_file_watcher_deliver_event (NetworkInadorHandle *handle, struct inotify_event *event, INotifyWD *inotwd) { static void network_inador_file_watcher_deliver_event (NetworkInadorHandle *handle, struct inotify_event *event, INotifyWD *inotwd) {
char path[4096];
if (event->name[0] == 0) {
snprintf (path, sizeof (path), "%s", inotwd->path);
} else {
snprintf (path, sizeof (path), "%s/%s", inotwd->path, event->name);
}
/* Este es el que pidió cierre de escritura */ /* Este es el que pidió cierre de escritura */
if (event->mask & IN_CLOSE_WRITE) { if (event->mask & IN_CLOSE_WRITE) {
if (inotwd->close_write_cb != NULL) { if (inotwd->close_write_cb != NULL) {
inotwd->close_write_cb (handle, NULL, inotwd->close_write_data); inotwd->close_write_cb (handle, path, inotwd->close_write_data);
} }
} }

View File

@ -28,6 +28,7 @@
#include "interfaces.h" #include "interfaces.h"
#include "ip-address.h" #include "ip-address.h"
#include "routes.h" #include "routes.h"
#include "rtables.h"
uint32_t *network_inador_list_ifaces (NetworkInadorHandle *handle) { uint32_t *network_inador_list_ifaces (NetworkInadorHandle *handle) {
uint32_t *memory; uint32_t *memory;
@ -351,3 +352,21 @@ uint32_t network_inador_nexthop_get_out_index (RouteNH *nexthop) {
return nexthop->out_index; return nexthop->out_index;
} }
int network_inador_rtables_get_count_tables (NetworkInadorHandle *handle) {
return handle->rtables_counter;
}
void network_inador_rtables_get_table_by_index (NetworkInadorHandle *handle, uint32_t nth, uint32_t *table_index, unsigned char *table_name, size_t table_name_size) {
RouteTable *table;
table = (RouteTable *) f_list_nth_data (f_list_first (handle->route_tables_names), nth);
if (table_index != NULL) {
*table_index = table->table;
}
if (table_name != NULL) {
strncpy (table_name, table->name, table_name_size);
}
}

View File

@ -41,6 +41,7 @@
#include "routes.h" #include "routes.h"
#include "resolv_manager.h" #include "resolv_manager.h"
#include "file_watcher.h" #include "file_watcher.h"
#include "rtables.h"
struct _NetworkInadorWatchedPID { struct _NetworkInadorWatchedPID {
unsigned int source; unsigned int source;
@ -259,6 +260,9 @@ NetworkInadorHandle * network_inador_init_handle (struct NetworkInadorOps *netwo
/* Inicializar las rutas */ /* Inicializar las rutas */
routes_init (handle); routes_init (handle);
/* Inicializar los nombres de las tablas de ruteo */
rtables_init (handle);
/* Inicializar el resolv.conf */ /* Inicializar el resolv.conf */
resolv_manager_init (handle); resolv_manager_init (handle);
@ -308,6 +312,7 @@ void network_inador_destroy_handle (NetworkInadorHandle *handle) {
} }
/* TODO: Liberar las listas ligadas aquí */ /* TODO: Liberar las listas ligadas aquí */
rtables_clean_up (handle);
routes_clean_up (handle); routes_clean_up (handle);
interfaces_clean_up (handle); interfaces_clean_up (handle);

View File

@ -32,15 +32,21 @@ typedef struct _IPAddr IPAddr;
typedef struct _Route Route; typedef struct _Route Route;
typedef void (*NetworkInadorDHCPEventCB) (NetworkInadorHandle *handle, Interface *iface, InterfaceDHCPClientInfo *dhcp_info, void *data); typedef void (*NetworkInadorDHCPEventCB) (NetworkInadorHandle *handle, Interface *iface, InterfaceDHCPClientInfo *dhcp_info, void *data);
typedef void (*NetworkInadorInterfaceAddEventCB) (NetworkInadorHandle *handle, Interface *iface, void *data); typedef void (*NetworkInadorInterfaceAddEventCB) (NetworkInadorHandle *handle, Interface *iface, void *data);
typedef void (*NetworkInadorInterfaceUpdateEventCB) (NetworkInadorHandle *handle, Interface *iface, void *data); typedef void (*NetworkInadorInterfaceUpdateEventCB) (NetworkInadorHandle *handle, Interface *iface, void *data);
typedef void (*NetworkInadorInterfaceDeleteEventCB) (NetworkInadorHandle *handle, uint32_t index, void *data); typedef void (*NetworkInadorInterfaceDeleteEventCB) (NetworkInadorHandle *handle, uint32_t index, void *data);
typedef void (*NetworkInadorIPAddEventCB) (NetworkInadorHandle *handle, IPAddr *addr, void *data); typedef void (*NetworkInadorIPAddEventCB) (NetworkInadorHandle *handle, IPAddr *addr, void *data);
typedef void (*NetworkInadorIPDelEventCB) (NetworkInadorHandle *handle, IPAddr *addr, void *data); typedef void (*NetworkInadorIPDelEventCB) (NetworkInadorHandle *handle, IPAddr *addr, void *data);
typedef void (*NetworkInadorRouteAddEventCB) (NetworkInadorHandle *handle, Route *route, void *data); typedef void (*NetworkInadorRouteAddEventCB) (NetworkInadorHandle *handle, Route *route, void *data);
typedef void (*NetworkInadorRouteUpdateEventCB) (NetworkInadorHandle *handle, Route *route, void *data); typedef void (*NetworkInadorRouteUpdateEventCB) (NetworkInadorHandle *handle, Route *route, void *data);
typedef void (*NetworkInadorRouteDelEventCB) (NetworkInadorHandle *handle, Route *route, void *data); typedef void (*NetworkInadorRouteDelEventCB) (NetworkInadorHandle *handle, Route *route, void *data);
typedef void (*NetworkInadorRouteTableAddEventCB) (NetworkInadorHandle *handle, uint32_t table_index, const char *table_name, void *data);
typedef void (*NetworkInadorRouteTableDelEventCB) (NetworkInadorHandle *handle, uint32_t table_index, void *data);
/* Pendiente notificar rutas */ /* Pendiente notificar rutas */
void network_manager_add_watch_dhcp (NetworkInadorHandle *handle, NetworkInadorDHCPEventCB cb, void *data); void network_manager_add_watch_dhcp (NetworkInadorHandle *handle, NetworkInadorDHCPEventCB cb, void *data);
void network_manager_add_watch_interface_added (NetworkInadorHandle *handle, NetworkInadorInterfaceAddEventCB cb, void *data); void network_manager_add_watch_interface_added (NetworkInadorHandle *handle, NetworkInadorInterfaceAddEventCB cb, void *data);
@ -53,5 +59,8 @@ void network_manager_add_watch_route_added (NetworkInadorHandle *handle, Network
void network_manager_add_watch_route_updated (NetworkInadorHandle *handle, NetworkInadorRouteUpdateEventCB cb, void *data); void network_manager_add_watch_route_updated (NetworkInadorHandle *handle, NetworkInadorRouteUpdateEventCB cb, void *data);
void network_manager_add_watch_route_deleted (NetworkInadorHandle *handle, NetworkInadorRouteDelEventCB cb, void *data); void network_manager_add_watch_route_deleted (NetworkInadorHandle *handle, NetworkInadorRouteDelEventCB cb, void *data);
void network_manager_add_watch_route_table_added (NetworkInadorHandle *handle, NetworkInadorRouteTableAddEventCB cb, void *data);
void network_manager_add_watch_route_table_deleted (NetworkInadorHandle *handle, NetworkInadorRouteTableDelEventCB cb, void *data);
#endif /* __NETWORK_INADOR_EVENTS_H__ */ #endif /* __NETWORK_INADOR_EVENTS_H__ */

View File

@ -64,6 +64,11 @@ typedef struct _NetworkInadorEventList {
void *route_update_event_data; void *route_update_event_data;
NetworkInadorRouteDelEventCB route_del_event_cb; NetworkInadorRouteDelEventCB route_del_event_cb;
void *route_del_event_data; void *route_del_event_data;
NetworkInadorRouteTableAddEventCB route_table_add_event_cb;
void *route_table_add_event_data;
NetworkInadorRouteTableDelEventCB route_table_del_event_cb;
void *route_table_del_event_data;
} NetworkInadorEventList; } NetworkInadorEventList;
/* La definición principal que engloba todo */ /* La definición principal que engloba todo */
@ -80,6 +85,7 @@ struct _NetworkInadorHandle {
int interfaces_counter; int interfaces_counter;
int route_v4_counter; int route_v4_counter;
int route_v6_counter; int route_v6_counter;
int rtables_counter;
/* Entradas para el resolv conf */ /* Entradas para el resolv conf */
FList *resolver_entries; FList *resolver_entries;

View File

@ -93,8 +93,12 @@ int interfaces_dhcp_client_stop (NetworkInadorHandle *handle, int index);
int routes_add (NetworkInadorHandle *handle, uint8_t route_family, uint8_t route_prefix, uint8_t route_tos, uint32_t route_table, uint8_t route_protocol, uint8_t route_scope, uint8_t route_type, void *dest, void *prefsrc, uint32_t route_priority, void *route_nexthops); int routes_add (NetworkInadorHandle *handle, uint8_t route_family, uint8_t route_prefix, uint8_t route_tos, uint32_t route_table, uint8_t route_protocol, uint8_t route_scope, uint8_t route_type, void *dest, void *prefsrc, uint32_t route_priority, void *route_nexthops);
int routes_del (NetworkInadorHandle *handle, uint8_t route_family, uint8_t route_prefix, uint8_t route_tos, uint32_t route_table, uint32_t route_priority, void *dest); int routes_del (NetworkInadorHandle *handle, uint8_t route_family, uint8_t route_prefix, uint8_t route_tos, uint32_t route_table, uint32_t route_priority, void *dest);
/* Funciones de tablas de ruteo */
/* Funciones de resolvconf */ /* Funciones de resolvconf */
void resolv_manager_process_resolvconf_entries (NetworkInadorHandle *handle, void *entries); void resolv_manager_process_resolvconf_entries (NetworkInadorHandle *handle, void *entries);
void resolv_manager_clear_entries_by_prog (NetworkInadorHandle *handle, const uint32_t iface_index, const char *prog);
/* Lista de getters */ /* Lista de getters */
uint32_t *network_inador_list_ifaces (NetworkInadorHandle *handle); uint32_t *network_inador_list_ifaces (NetworkInadorHandle *handle);
@ -144,6 +148,9 @@ uint8_t network_inador_nexthop_get_flags (RouteNH *nexthop);
uint8_t network_inador_nexthop_get_weight (RouteNH *nexthop); uint8_t network_inador_nexthop_get_weight (RouteNH *nexthop);
uint32_t network_inador_nexthop_get_out_index (RouteNH *nexthop); uint32_t network_inador_nexthop_get_out_index (RouteNH *nexthop);
int network_inador_rtables_get_count_tables (NetworkInadorHandle *handle);
void network_inador_rtables_get_table_by_index (NetworkInadorHandle *handle, uint32_t nth, uint32_t *table_index, unsigned char *table_name, size_t table_name_size);
void *network_inador_route_append_nexthop (void *list, uint8_t family, void *gw, uint32_t out_iface, uint8_t weight, uint8_t flags); void *network_inador_route_append_nexthop (void *list, uint8_t family, void *gw, uint32_t out_iface, uint8_t weight, uint8_t flags);
void network_inador_route_free_all_nexthops (void *list); void network_inador_route_free_all_nexthops (void *list);

View File

@ -64,7 +64,7 @@ int resolv_manager_sort_entries (const void *a, const void *b, void * data) {
return 0; return 0;
} }
void resolv_manager_clear_entries_by_prog (NetworkInadorHandle *handle, const int iface_index, const char *prog) { void resolv_manager_clear_entries_by_prog (NetworkInadorHandle *handle, uint32_t iface_index, const char *prog) {
FList *g; FList *g;
ResolvConfEntry *entry; ResolvConfEntry *entry;
int do_write = 0; int do_write = 0;

View File

@ -29,7 +29,7 @@
#include "interfaces.h" #include "interfaces.h"
void resolv_manager_init (NetworkInadorHandle *handle); void resolv_manager_init (NetworkInadorHandle *handle);
void resolv_manager_clear_entries_by_prog (NetworkInadorHandle *handle, const int iface_index, const char *prog); void resolv_manager_clear_entries_by_prog (NetworkInadorHandle *handle, const uint32_t iface_index, const char *prog);
void resolv_manager_process_resolvconf_entries (NetworkInadorHandle *handle, void *entries); void resolv_manager_process_resolvconf_entries (NetworkInadorHandle *handle, void *entries);
void resolv_manager_process_dhcp_nameservers (NetworkInadorHandle *handle, Interface *iface); void resolv_manager_process_dhcp_nameservers (NetworkInadorHandle *handle, Interface *iface);
void resolv_manager_clear_dhcp_nameservers (NetworkInadorHandle *handle, Interface *iface); void resolv_manager_clear_dhcp_nameservers (NetworkInadorHandle *handle, Interface *iface);

View File

@ -753,147 +753,9 @@ void routes_ask (NetworkInadorHandle *handle) {
} }
} }
int _routes_table_find_by_number (const void * left, const void * right) {
RouteTable *a, *b;
a = (RouteTable *) left;
b = (RouteTable *) right;
return a->table != b->table;
}
void _routes_table_parse_file (NetworkInadorHandle *handle, FILE *fd) {
FList *g;
int ret;
RouteTable *rtable, temp_table;
char buffer[2048];
while (fgets (buffer, sizeof (buffer), fd), feof (fd) == 0) {
if (buffer[0] == '#') continue; /* Ignorar las lineas con comentarios */
ret = sscanf (buffer, "%d %s", &(temp_table.table), temp_table.name);
if (ret < 2) {
continue;
}
g = f_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 *) 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));
handle->route_tables_names = f_list_append (handle->route_tables_names, rtable);
}
}
void routes_tables_read (NetworkInadorHandle *handle, int do_notify) {
FILE *fd;
FList *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;
}
//f_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 = f_list_delete_link (handle->route_tables_names, g);
if (do_notify) {
//manager_send_event_route_table_del (handle, rtable);
}
free (rtable);
}
g = h;
}
g = handle->route_tables_names;
while (g != NULL) {
rtable = (RouteTable *) g->data;
if (rtable->was_new) {
if (do_notify) {
//manager_send_event_route_table_add (handle, rtable);
}
rtable->was_new = 0;
}
g = g->next;
}
}
void routes_init (NetworkInadorHandle *handle) { void routes_init (NetworkInadorHandle *handle) {
/* Si es la primera vez que nos llaman, descargar una primera lista de interfaces */ /* Si es la primera vez que nos llaman, descargar una primera lista de interfaces */
routes_ask (handle); routes_ask (handle);
/* Inicializar los nombres de las tablas de ruteo */
routes_tables_read (handle, FALSE);
} }
void routes_clean_up (NetworkInadorHandle *handle) { void routes_clean_up (NetworkInadorHandle *handle) {

View File

@ -66,13 +66,6 @@ typedef struct _Route {
int for_delete; int for_delete;
} Route; } Route;
typedef struct {
uint32_t table;
char name[256];
int for_delete, was_new;
} RouteTable;
void routes_init (NetworkInadorHandle *handle); void routes_init (NetworkInadorHandle *handle);
void routes_ask (NetworkInadorHandle *handle); void routes_ask (NetworkInadorHandle *handle);
int routes_receive_message_newroute (struct nl_msg *msg, void *arg); int routes_receive_message_newroute (struct nl_msg *msg, void *arg);

218
lib/rtables.c 100644
View File

@ -0,0 +1,218 @@
/*
* rtables.c
* This file is part of Network-inador
*
* Copyright (C) 2025 - Félix Arreola Rodríguez
*
* Network-inador 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.
*
* Network-inador 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 Network-inador; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <linux/rtnetlink.h>
#include <netlink/socket.h>
#include <netlink/msg.h>
#include "flist.h"
#include "network-inador-private.h"
#include "rtables.h"
#include "event_notify.h"
#include "file_watcher.h"
static int _routes_table_find_by_number (const void * left, const void * right) {
RouteTable *a, *b;
a = (RouteTable *) left;
b = (RouteTable *) right;
return a->table != b->table;
}
static void _routes_table_parse_file (NetworkInadorHandle *handle, FILE *fd) {
FList *g;
int ret;
RouteTable *rtable, temp_table;
char buffer[2048];
while (fgets (buffer, sizeof (buffer), fd), feof (fd) == 0) {
if (buffer[0] == '#') continue; /* Ignorar las lineas con comentarios */
ret = sscanf (buffer, "%d %s", &(temp_table.table), temp_table.name);
if (ret < 2) {
continue;
}
if (temp_table.table == 0) continue; /* Omitir la tabla número 0 */
g = f_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;
printf ("Tabla ya existe en la lista ligada: %d\n", temp_table.table);
rtable->for_delete = 0;
rtable->was_new = 0;
} else {
printf ("Creando tabla en la lista ligada: %i, %s\n", temp_table.table, temp_table.name);
/* No existe, crear nueva */
rtable = (RouteTable *) malloc (sizeof (RouteTable));
rtable->table = temp_table.table;
rtable->for_delete = 0;
rtable->was_new = 1;
handle->route_tables_names = f_list_append (handle->route_tables_names, rtable);
handle->rtables_counter++;
}
/* En cualquier caso actualizar el nombre */
strncpy (rtable->name, temp_table.name, sizeof (rtable->name));
}
}
static void routes_tables_read_all (NetworkInadorHandle *handle, int do_notify) {
FILE *fd;
FList *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;
}
/* Intentar abrir /etc/iproute2/rt_tables */
fd = fopen ("/etc/iproute2/rt_tables", "r");
if (fd != NULL) {
printf ("Parsing main rt_tables file\n");
_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);
printf ("Parsing %s secundary\n", buffer);
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 = f_list_delete_link (handle->route_tables_names, g);
handle->rtables_counter--;
if (do_notify) {
network_manager_trigger_route_table_deleted_event (handle, rtable->table);
}
free (rtable);
}
g = h;
}
g = handle->route_tables_names;
while (g != NULL) {
rtable = (RouteTable *) g->data;
if (rtable->was_new) {
if (do_notify) {
network_manager_trigger_route_table_added_event (handle, rtable->table, rtable->name);
}
rtable->was_new = 0;
}
g = g->next;
}
}
static void rtables_notify_close_write_cb (NetworkInadorHandle *handle, const char *path, void *data) {
/* Cuando se nos notifique acerca de un cambio en el /etc/iproute2/rt_tables re-leer el archivo */
routes_tables_read_all (handle, TRUE);
}
static void rtables_notify_directory_close_write_cb (NetworkInadorHandle *handle, const char *path, void *data) {
int path_len;
path_len = strlen (path);
if (path_len < 5) {
/* Si ni siquiera tiene 5 letras ".conf", este archivo no nos interesa */
return;
}
if (strcmp (&path[path_len - 5], ".conf") != 0) return;
/* Cuando se nos notifique acerca de un cambio en el resolv.conf re-leer el archivo */
routes_tables_read_all (handle, TRUE);
}
void rtables_init (NetworkInadorHandle *handle) {
network_inador_file_watcher_add_file (handle, "/etc/iproute2/rt_tables", rtables_notify_close_write_cb, NULL);
/* TODO: La vigilancia de directorios necesita vigilar eliminar archivos y archivos movidos */
network_inador_file_watcher_add_file (handle, "/etc/iproute2/rt_tables.d/", rtables_notify_directory_close_write_cb, NULL);
routes_tables_read_all (handle, FALSE);
}
void rtables_clean_up (NetworkInadorHandle *handle) {
f_list_free_full (handle->route_tables_names, free);
handle->route_tables_names = NULL;
handle->rtables_counter = 0;
}

44
lib/rtables.h 100644
View File

@ -0,0 +1,44 @@
/*
* rtables.h
* This file is part of Network-inador
*
* Copyright (C) 2025 - Félix Arreola Rodríguez
*
* Network-inador 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.
*
* Network-inador 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 Network-inador; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef __RTABLES_H__
#define __RTABLES_H__
#include <stdint.h>
#include <netlink/socket.h>
#include <netlink/msg.h>
#include "network-inador-private.h"
typedef struct {
uint32_t table;
char name[256];
int for_delete, was_new;
} RouteTable;
void rtables_init (NetworkInadorHandle *handle);
void rtables_clean_up (NetworkInadorHandle *handle);
#endif /* __RTABLES_H__ */

View File

@ -7,6 +7,7 @@ network_inador_SOURCES = main.c \
manager-ip.c manager-ip.h \ manager-ip.c manager-ip.h \
manager-bridge.c manager-bridge.h \ manager-bridge.c manager-bridge.h \
manager-routes.c manager-routes.h \ manager-routes.c manager-routes.h \
manager-rtables.c manager-rtables.h \
manager-resolvconf.c manager-resolvconf.h manager-resolvconf.c manager-resolvconf.h
resolvconf_SOURCES = resolv_conf_helper.c \ resolvconf_SOURCES = resolv_conf_helper.c \

View File

@ -0,0 +1,137 @@
/*
* manager-routes.c
* This file is part of Network-inador
*
* Copyright (C) 2025 - Félix Arreola Rodríguez
*
* Network-inador 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.
*
* Network-inador 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 Network-inador; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <linux/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "manager-private.h"
#include "network-inador-public.h"
#include "network-inador-manager.h"
/* Empaquetador de datos */
int _manager_pack_route_table_info (unsigned char *buffer, uint32_t table_index, const char *table_name) {
int name_len;
memcpy (&buffer[0], &table_index, 4);
name_len = strlen (table_name);
buffer[4] = name_len;
memcpy (&buffer[5], table_name, name_len);
return 5 + name_len;
}
/* Los comandos que verdaderamente envian */
void _manager_send_route_table (ManagerClientInfo *manager_client, uint32_t table_index, const char *table_name, uint8_t is_event) {
unsigned char buffer[300];
int size;
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;
}
size = 2 + _manager_pack_route_table_info (&buffer[2], table_index, table_name);
send (manager_client->fd, buffer, size, 0);
}
void _manager_send_route_table_deleted (ManagerClientInfo *manager_client, uint32_t table_index) {
unsigned char buffer[80];
buffer[0] = NET_INADOR_TYPE_EVENT;
buffer[1] = NET_INADOR_EVENT_ROUTE_TABLE_REMOVED;
memcpy (&buffer[2], &table_index, 4);
send (manager_client->fd, buffer, 6, 0);
}
void _manager_route_table_handle_list_tables (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) {
int g, table_count;
uint32_t table, table_wanted;
char table_name[256];
if (buffer_len < 6) {
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_LIST_ROUTE_TABLES);
return;
}
memcpy (&table_wanted, &buffer[2], 4);
table_count = network_inador_rtables_get_count_tables (manager_client->manager->handle);
for (g = 0; g < table_count; g++) {
network_inador_rtables_get_table_by_index (manager_client->manager->handle, g, &table, table_name, sizeof (table_name));
if (table_wanted != 0 && table_wanted != table) continue;
_manager_send_route_table (manager_client, table, table_name, FALSE);
}
_manager_send_end_command (manager_client, NET_INADOR_COMMAND_LIST_ROUTE_TABLES);
}
/* Los eventos que vienen desde la librería */
void _manager_route_table_added_event_cb (NetworkInadorHandle *handle, uint32_t table_index, const char *table_name, void *data) {
Manager *manager = (Manager *) data;
GList *g;
ManagerClientInfo *manager_client;
printf ("___ MANAGER ___ Informando tabla de ruteo agregada: %s (%i)\n", table_name, table_index);
for (g = manager->connected_client_list; g != NULL; g = g->next) {
manager_client = (ManagerClientInfo *) g->data;
if (manager_client->wanted_events & NET_INADOR_EVENT_MASK_ROUTE_TABLES) {
printf ("___ MANAGER ___ Informando a la conexión (%i)\n", manager_client->fd);
_manager_send_route_table (manager_client, table_index, table_name, TRUE);
}
}
}
void _manager_route_table_deleted_event_cb (NetworkInadorHandle *handle, uint32_t table_index, void *data) {
Manager *manager = (Manager *) data;
GList *g;
ManagerClientInfo *manager_client;
printf ("___ MANAGER ___ Informando tabla de ruteo eliminada: %i\n", table_index);
for (g = manager->connected_client_list; g != NULL; g = g->next) {
manager_client = (ManagerClientInfo *) g->data;
if (manager_client->wanted_events & NET_INADOR_EVENT_MASK_ROUTE_TABLES) {
printf ("___ MANAGER ___ Informando a la conexión (%i)\n", manager_client->fd);
_manager_send_route_table_deleted (manager_client, table_index);
}
}
}

View File

@ -0,0 +1,40 @@
/*
* manager-rtables.h
* This file is part of Network-inador
*
* Copyright (C) 2025 - Félix Arreola Rodríguez
*
* Network-inador 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.
*
* Network-inador 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 Network-inador; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef __MANAGER_RTABLES_H__
#define __MANAGER_RTABLES_H__
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "manager-private.h"
#include "network-inador-public.h"
#include "network-inador-manager.h"
void _manager_route_table_handle_list_tables (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len);
void _manager_route_table_added_event_cb (NetworkInadorHandle *handle, uint32_t table_index, const char *table_name, void *data);
void _manager_route_table_deleted_event_cb (NetworkInadorHandle *handle, uint32_t table_index, void *data);
#endif /* __MANAGER_RTABLES_H__ */

View File

@ -49,6 +49,7 @@
#include "manager-bridge.h" #include "manager-bridge.h"
#include "manager-routes.h" #include "manager-routes.h"
#include "manager-resolvconf.h" #include "manager-resolvconf.h"
#include "manager-rtables.h"
#define COMMAND_SOCKET_PATH "/tmp/network-inador.socket" #define COMMAND_SOCKET_PATH "/tmp/network-inador.socket"
@ -208,9 +209,9 @@ static gboolean _manager_on_client_data_recv (GIOChannel *source, GIOCondition c
case NET_INADOR_COMMAND_REMOVE_ROUTE: case NET_INADOR_COMMAND_REMOVE_ROUTE:
_manager_route_handle_del_route (manager_client, buffer, bytes); _manager_route_handle_del_route (manager_client, buffer, bytes);
break; break;
/*case NET_INADOR_COMMAND_LIST_ROUTE_TABLES: case NET_INADOR_COMMAND_LIST_ROUTE_TABLES:
_manager_send_list_route_tables (manager_client, buffer, bytes); _manager_route_table_handle_list_tables (manager_client, buffer, bytes);
break;*/ break;
case NET_INADOR_COMMAND_RESOLVCONF_FEED: case NET_INADOR_COMMAND_RESOLVCONF_FEED:
_manager_resolvconf_handle_feed (manager_client, buffer, bytes); _manager_resolvconf_handle_feed (manager_client, buffer, bytes);
break; break;
@ -333,6 +334,9 @@ Manager * manager_new (NetworkInadorHandle *handle, int type) {
network_manager_add_watch_route_updated (handle, _manager_route_updated_event_cb, manager); network_manager_add_watch_route_updated (handle, _manager_route_updated_event_cb, manager);
network_manager_add_watch_route_deleted (handle, _manager_route_deleted_event_cb, manager); network_manager_add_watch_route_deleted (handle, _manager_route_deleted_event_cb, manager);
network_manager_add_watch_route_table_added (handle, _manager_route_table_added_event_cb, manager);
network_manager_add_watch_route_table_deleted (handle, _manager_route_table_deleted_event_cb, manager);
return manager; return manager;
} }