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