From 8482a52522b7127912d3c3934786bd1be04fa359 Mon Sep 17 00:00:00 2001 From: Koichiro IWAO Date: Wed, 31 May 2023 11:34:50 +0900 Subject: [PATCH] Cedar/VLanUnix: Make NicDelete work on FreeBSD In contrast to Linux, FreeBSD's tap devices are still plumbed after fd closed. The tap device must be destroyed in addition to closing fd to delete virtual network interfaces used for VPN connection. NicDelete command now works properly and virtual network interfaces used by vpnclient are cleaned up when shutting down vpnclient. --- src/Cedar/VLanUnix.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/Cedar/VLanUnix.c b/src/Cedar/VLanUnix.c index b4ae5f35..1bc5c73e 100644 --- a/src/Cedar/VLanUnix.c +++ b/src/Cedar/VLanUnix.c @@ -569,12 +569,40 @@ void UnixCloseTapDevice(int fd) close(fd); } +// Destroy the tap device (for FreeBSD) +// FreeBSD tap device is still plumbed after closing fd so need to destroy after close +void UnixDestroyTapDevice(char *name) +{ +#ifdef UNIX_BSD + struct ifreq ifr; + char eth_name[MAX_SIZE]; + int s; + + Zero(&ifr, sizeof(ifr)); + GenerateTunName(name, UNIX_VLAN_IFACE_PREFIX, eth_name, sizeof(eth_name)); + StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), eth_name); + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s == -1) + { + return; + } + ioctl(s, SIOCIFDESTROY, &ifr); + + close(s); +#endif // UNIX_BSD +} + #else // NO_VLAN void UnixCloseTapDevice(int fd) { } +void UnixDestroyTapDevice(char *name) +{ +} + int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address, bool create_up) { return -1; @@ -769,6 +797,9 @@ void UnixVLanDelete(char *name) if (t != NULL) { UnixCloseTapDevice(t->fd); +#ifdef UNIX_BSD + UnixDestroyTapDevice(t->Name); +#endif Delete(unix_vlan, t); Free(t); } @@ -815,6 +846,9 @@ void UnixVLanFree() UNIX_VLAN_LIST *t = LIST_DATA(unix_vlan, i); UnixCloseTapDevice(t->fd); +#ifdef UNIX_BSD + UnixDestroyTapDevice(t->Name); +#endif Free(t); }