Browse Source

Fix: Delete system routes on shutdown

- Add tun_route_del_all() to delete routes from config
- Use netsh for route deletion on Windows (like add)
- Store route_subnets in UTUN_INSTANCE for cleanup
- Delete routes in utun_instance_destroy() before tun_close()
nodeinfo-routing-update
jeka 7 months ago
parent
commit
9269bc9c61
  1. 60
      src/tun_route.c
  2. 12
      src/tun_route.h
  3. 9
      src/utun_instance.c
  4. 4
      src/utun_instance.h

60
src/tun_route.c

@ -158,10 +158,9 @@ int tun_route_add(uint32_t ifindex, uint32_t network, uint8_t prefix_len) {
return ip_route_cmd(ifname, ntohl(network), prefix_len, "add");
}
int tun_route_del(const char *ifname, uint32_t network, uint8_t prefix_len) {
int ifindex = if_nametoindex(ifname);
int tun_route_del(uint32_t ifindex, uint32_t network, uint8_t prefix_len) {
if (ifindex == 0) {
DEBUG_ERROR(DEBUG_CATEGORY_TUN, "Interface %s not found", ifname);
DEBUG_ERROR(DEBUG_CATEGORY_TUN, "tun_route_del: ifindex is 0");
return -1;
}
@ -173,7 +172,9 @@ int tun_route_del(const char *ifname, uint32_t network, uint8_t prefix_len) {
}
// Fallback to ip route command
DEBUG_WARN(DEBUG_CATEGORY_TUN, "Netlink failed, trying ip route command for %s", ifname);
char ifname[16];
snprintf(ifname, sizeof(ifname), "%u", ifindex);
DEBUG_WARN(DEBUG_CATEGORY_TUN, "Netlink failed, trying ip route command for ifindex %u", ifindex);
return ip_route_cmd(ifname, ntohl(network), prefix_len, "del");
}
@ -247,17 +248,35 @@ int tun_route_add(uint32_t ifindex, uint32_t network, uint8_t prefix_len) {
return 0;
}
int tun_route_del(const char *ifname, uint32_t network, uint8_t prefix_len) {
int tun_route_del(uint32_t ifindex, uint32_t network, uint8_t prefix_len) {
if (ifindex == 0) {
DEBUG_ERROR(DEBUG_CATEGORY_TUN, "tun_route_del: ifindex is 0");
return -1;
}
struct in_addr dest_addr;
dest_addr.s_addr = htonl(network);
char cmd[256];
snprintf(cmd, sizeof(cmd), "netsh interface ip delete route %s/%d interface=%lu store=active",
inet_ntoa(dest_addr), prefix_len, (unsigned long)ifindex);
int sys_ret = system(cmd);
if (sys_ret == 0) {
DEBUG_INFO(DEBUG_CATEGORY_TUN, "Deleted route %s/%d via ifindex=%lu",
inet_ntoa(dest_addr), prefix_len, (unsigned long)ifindex);
return 0;
}
MIB_IPFORWARDROW route;
memset(&route, 0, sizeof(route));
route.dwForwardDest = htonl(network);
route.dwForwardMask = prefix_to_netmask(prefix_len);
route.dwForwardIfIndex = if_nametoindex(ifname);
route.dwForwardIfIndex = ifindex;
DWORD ret = DeleteIpForwardEntry(&route);
if (ret != NO_ERROR) {
DEBUG_ERROR(DEBUG_CATEGORY_TUN, "Failed to delete route: %lu", ret);
DEBUG_ERROR(DEBUG_CATEGORY_TUN, "Failed to delete route %s/%d: %lu",
inet_ntoa(dest_addr), prefix_len, ret);
return -1;
}
return 0;
@ -299,6 +318,24 @@ int tun_route_flush(const char *ifname) {
return 0;
}
int tun_route_del_all(uint32_t ifindex, struct CFG_ROUTE_ENTRY *routes) {
int count = 0;
struct CFG_ROUTE_ENTRY *entry = routes;
while (entry) {
uint32_t network = ntohl(entry->ip.addr.v4.s_addr);
if (entry->ip.family == AF_INET) {
if (tun_route_del(ifindex, network, entry->netmask) == 0) {
count++;
}
}
entry = entry->next;
}
DEBUG_INFO(DEBUG_CATEGORY_TUN, "Deleted %d routes via ifindex=%lu", count, (unsigned long)ifindex);
return count;
}
#else
// BSD / macOS routing socket implementation
@ -396,10 +433,9 @@ int tun_route_add(uint32_t ifindex, uint32_t network, uint8_t prefix_len) {
return route_cmd(ifname, network, prefix_len, "add");
}
int tun_route_del(const char *ifname, uint32_t network, uint8_t prefix_len) {
int ifindex = if_nametoindex(ifname);
int tun_route_del(uint32_t ifindex, uint32_t network, uint8_t prefix_len) {
if (ifindex == 0) {
DEBUG_ERROR(DEBUG_CATEGORY_TUN, "Interface %s not found", ifname);
DEBUG_ERROR(DEBUG_CATEGORY_TUN, "tun_route_del: ifindex is 0");
return -1;
}
@ -409,7 +445,9 @@ int tun_route_del(const char *ifname, uint32_t network, uint8_t prefix_len) {
}
// Fallback to route command
DEBUG_WARN(DEBUG_CATEGORY_TUN, "Routing socket failed, trying route command for %s", ifname);
char ifname[16];
snprintf(ifname, sizeof(ifname), "%u", ifindex);
DEBUG_WARN(DEBUG_CATEGORY_TUN, "Routing socket failed, trying route command for ifindex %u", ifindex);
return route_cmd(ifname, network, prefix_len, "delete");
}

12
src/tun_route.h

@ -22,12 +22,20 @@ int tun_route_add(uint32_t ifindex, uint32_t network, uint8_t prefix_len);
/**
* @brief Delete system route for a subnet via TUN interface
* @param ifname Interface name (e.g., "tun0")
* @param ifindex Interface index
* @param network Network address in host byte order
* @param prefix_len Prefix length (1-32)
* @return 0 on success, -1 on error
*/
int tun_route_del(const char *ifname, uint32_t network, uint8_t prefix_len);
int tun_route_del(uint32_t ifindex, uint32_t network, uint8_t prefix_len);
/**
* @brief Delete all system routes from config entries
* @param ifindex Interface index
* @param routes Linked list of route entries to delete
* @return Number of routes deleted
*/
int tun_route_del_all(uint32_t ifindex, struct CFG_ROUTE_ENTRY *routes);
/**
* @brief Delete all system routes via specified interface

9
src/utun_instance.c

@ -108,6 +108,7 @@ static int instance_init_common(struct UTUN_INSTANCE* instance, struct UASYNC* u
if (config->route_subnets) {
int added = tun_route_add_all(instance->tun->ifindex, instance->tun->ifname, config->route_subnets);
DEBUG_INFO(DEBUG_CATEGORY_TUN, "Added %d system routes for TUN interface", added);
instance->route_subnets = config->route_subnets;
}
} else {
DEBUG_INFO(DEBUG_CATEGORY_TUN, "TUN initialization disabled - skipping TUN device setup");
@ -237,9 +238,11 @@ void utun_instance_destroy(struct UTUN_INSTANCE *instance) {
if (instance->tun) {
DEBUG_INFO(DEBUG_CATEGORY_TUN, "Closing TUN interface: %s", instance->tun->ifname);
// Flush all system routes for this interface
tun_route_flush(instance->tun->ifname);
DEBUG_INFO(DEBUG_CATEGORY_TUN, "Flushed system routes for %s", instance->tun->ifname);
// Delete system routes added at startup
if (instance->tun->ifindex && instance->route_subnets) {
int deleted = tun_route_del_all(instance->tun->ifindex, instance->route_subnets);
DEBUG_INFO(DEBUG_CATEGORY_TUN, "Deleted %d system routes for TUN interface", deleted);
}
tun_close(instance->tun);
instance->tun = NULL;

4
src/utun_instance.h

@ -7,6 +7,7 @@
#include "../lib/memory_pool.h"
#include "secure_channel.h"
#include "etcp_api.h"
#include "config_parser.h"
// Forward declarations
struct utun_config;
@ -26,6 +27,9 @@ struct UTUN_INSTANCE {
// TUN interface
struct tun_if* tun;
// Route subnets (for cleanup on shutdown)
struct CFG_ROUTE_ENTRY* route_subnets;
struct ROUTE_TABLE* rt;
struct ROUTE_BGP* bgp; // BGP module for route exchange

Loading…
Cancel
Save