@ -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 " ) ;
}