1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2025-07-06 07:44:57 +03:00

Put TUN down on client disconnect.

On startup client creates TUN interface in UP state and kept it UP even
if connection to the server was lost. Creating interface in DOWN state,
turning it UP on successful (re-)connection to server and DOWN on either
disconnect or connection loss would enable DHCP client (say dhclient5)
to detect necessity for lease renewal.

Added a client configuration parameter to create TUN interface in DOWN
state and commands to enable, disable, and query the configuration
parameter.
Enabling the parameter causes client to put all unused TUN interfaces
DOWN, create new TUN interfaces in DOWN state, and turn TUN interfaces
corresponding to active sessions DOWN on connection loss or
disconnecting from server.
Disabling the parameter forces client to turn all TUN interfaces UP and
create new TUN interfaces in UP state.
Default value is 'Disable'.
This commit is contained in:
Joshua Perry
2018-08-05 17:35:57 +02:00
committed by Davide Beatrici
parent 828d3b2ffb
commit 59e1483dbf
16 changed files with 436 additions and 37 deletions

View File

@ -598,7 +598,7 @@ ETH *OpenEthLinux(char *name, bool local, bool tapmode, char *tapaddr)
{
#ifndef NO_VLAN
// In tap mode
VLAN *v = NewTap(name, tapaddr);
VLAN *v = NewTap(name, tapaddr, true);
if (v == NULL)
{
return NULL;

View File

@ -3854,6 +3854,7 @@ void InRpcClientConfig(CLIENT_CONFIG *c, PACK *p)
c->KeepConnectProtocol = PackGetInt(p, "KeepConnectProtocol");
c->KeepConnectInterval = PackGetInt(p, "KeepConnectInterval");
c->AllowRemoteConfig = PackGetInt(p, "AllowRemoteConfig") == 0 ? false : true;
c->NicDownOnDisconnect = PackGetBool(p, "NicDownOnDisconnect");
PackGetStr(p, "KeepConnectHost", c->KeepConnectHost, sizeof(c->KeepConnectHost));
}
void OutRpcClientConfig(PACK *p, CLIENT_CONFIG *c)
@ -3869,6 +3870,7 @@ void OutRpcClientConfig(PACK *p, CLIENT_CONFIG *c)
PackAddInt(p, "KeepConnectProtocol", c->KeepConnectProtocol);
PackAddInt(p, "KeepConnectInterval", c->KeepConnectInterval);
PackAddInt(p, "AllowRemoteConfig", c->AllowRemoteConfig);
PackAddBool(p, "NicDownOnDisconnect", c->NicDownOnDisconnect);
PackAddStr(p, "KeepConnectHost", c->KeepConnectHost);
}
@ -6657,7 +6659,7 @@ bool CtConnect(CLIENT *c, RPC_CLIENT_CONNECT *connect)
CLog(c, "LC_CONNECT", connect->AccountName);
r->ClientSession = NewClientSessionEx(c->Cedar, r->ClientOption, r->ClientAuth, pa, r);
r->ClientSession = NewClientSessionEx(c->Cedar, r->ClientOption, r->ClientAuth, pa, r, &c->Config.NicDownOnDisconnect);
Notify(r->ClientSession, CLIENT_NOTIFY_ACCOUNT_CHANGED);
ret = true;
@ -6674,6 +6676,82 @@ bool CtConnect(CLIENT *c, RPC_CLIENT_CONNECT *connect)
return ret;
}
// Put all unused TUN interfaces down
// Requires account and VLan lists of the CLIENT argument to be already locked
bool CtVLansDown(CLIENT *c)
{
#ifndef UNIX_LINUX
return true;
#else
int i;
LIST *tmpVLanList;
UNIX_VLAN t, *r;
bool result = true;
if (c == NULL)
{
return false;
}
tmpVLanList = CloneList(c->UnixVLanList);
if (tmpVLanList == NULL)
{
return false;
}
// Remove from tmpVLanList all VLans corresponding to active sessions
for (i = 0; i < LIST_NUM(c->AccountList); ++i)
{
ACCOUNT *a = LIST_DATA(c->AccountList, i);
if (a->ClientSession == NULL)
{
continue;
}
Zero(&t, sizeof(t));
StrCpy(t.Name, sizeof(t.Name), a->ClientOption->DeviceName);
r = Search(tmpVLanList, &t);
Delete(tmpVLanList, r);
}
// Set down every VLan in tmpVLanList
for (i = 0; i < LIST_NUM(tmpVLanList) && result; ++i)
{
r = LIST_DATA(tmpVLanList, i);
result = UnixVLanSetState(r->Name, false);
// [MP:] Should we report *critical* error on failure?
}
ReleaseList(tmpVLanList);
return result;
#endif
}
// Put all TUN interfaces up
// Requires VLan list of the CLIENT argument to be already locked
bool CtVLansUp(CLIENT *c)
{
#ifndef UNIX_LINUX
return true;
#else
int i;
UNIX_VLAN *r;
if (c == NULL)
{
return false;
}
for (i = 0; i < LIST_NUM(c->UnixVLanList); ++i)
{
r = LIST_DATA(c->UnixVLanList, i);
UnixVLanSetState(r->Name, true);
}
return true;
#endif
}
// Get the account information
bool CtGetAccount(CLIENT *c, RPC_CLIENT_GET_ACCOUNT *a)
{
@ -6894,6 +6972,20 @@ bool CtSetClientConfig(CLIENT *c, CLIENT_CONFIG *o)
}
Unlock(k->lock);
// Apply TAP state
LockList(c->AccountList);
LockList(c->UnixVLanList);
if (o->NicDownOnDisconnect)
{
CtVLansDown(c);
}
else
{
CtVLansUp(c);
}
UnlockList(c->UnixVLanList);
UnlockList(c->AccountList);
return true;
}
@ -8302,8 +8394,8 @@ bool CtCreateVLan(CLIENT *c, RPC_CLIENT_CREATE_VLAN *create)
GenMacAddress(r->MacAddress);
StrCpy(r->Name, sizeof(r->Name), create->DeviceName);
// Create a Tap
if (UnixVLanCreate(r->Name, r->MacAddress) == false)
// Create a TUN
if (UnixVLanCreate(r->Name, r->MacAddress, !c->Config.NicDownOnDisconnect) == false)
{
// Failure
Free(r);
@ -9371,6 +9463,7 @@ void CiLoadClientConfig(CLIENT_CONFIG *c, FOLDER *f)
c->AllowRemoteConfig = CfgGetBool(f, "AllowRemoteConfig");
c->KeepConnectInterval = MAKESURE(CfgGetInt(f, "KeepConnectInterval"), KEEP_INTERVAL_MIN, KEEP_INTERVAL_MAX);
c->NoChangeWcmNetworkSettingOnWindows8 = CfgGetBool(f, "NoChangeWcmNetworkSettingOnWindows8");
c->NicDownOnDisconnect = CfgGetBool(f, "NicDownOnDisconnect");
}
// Read the client authentication data
@ -9699,7 +9792,7 @@ void CiLoadVLan(CLIENT *c, FOLDER *f)
Add(c->UnixVLanList, v);
#ifdef OS_UNIX
UnixVLanCreate(v->Name, v->MacAddress);
UnixVLanCreate(v->Name, v->MacAddress, !c->Config.NicDownOnDisconnect);
#endif // OS_UNIX
}
@ -9923,6 +10016,7 @@ void CiWriteClientConfig(FOLDER *cc, CLIENT_CONFIG *config)
CfgAddBool(cc, "AllowRemoteConfig", config->AllowRemoteConfig);
CfgAddInt(cc, "KeepConnectInterval", config->KeepConnectInterval);
CfgAddBool(cc, "NoChangeWcmNetworkSettingOnWindows8", config->NoChangeWcmNetworkSettingOnWindows8);
CfgAddBool(cc, "NicDownOnDisconnect", config->NicDownOnDisconnect);
}
// Write the client authentication data

View File

@ -195,6 +195,7 @@ struct CLIENT_CONFIG
UINT KeepConnectProtocol; // Protocol
UINT KeepConnectInterval; // Interval
bool NoChangeWcmNetworkSettingOnWindows8; // Don't change the WCM network settings on Windows 8
bool NicDownOnDisconnect; // Put NIC down on disconnect/connection loss and put it up again after connecting to VPN server
};
// Version acquisition

View File

@ -3119,6 +3119,9 @@ void PcMain(PC *pc)
{"AccountImport", PcAccountImport},
{"RemoteEnable", PcRemoteEnable},
{"RemoteDisable", PcRemoteDisable},
{"TUNDownOnDisconnectEnable", PcTunDownOnDisconnectEnable},
{"TUNDownOnDisconnectDisable", PcTunDownOnDisconnectDisable},
{"TUNDownOnDisconnectGet", PcTunDownOnDisconnectGet},
{"KeepEnable", PcKeepEnable},
{"KeepDisable", PcKeepDisable},
{"KeepSet", PcKeepSet},
@ -6641,6 +6644,136 @@ UINT PcRemoteDisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
return ret;
}
// Enable turning TUN interface up/down on client connect/disconnect
UINT PcTunDownOnDisconnectEnable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{
LIST *o;
PC *pc = (PC *)param;
UINT ret = ERR_NO_ERROR;
CLIENT_CONFIG t;
// Get the parameter list
o = ParseCommandList(c, cmd_name, str, NULL, 0);
if (o == NULL)
{
return ERR_INVALID_PARAMETER;
}
// RPC call
Zero(&t, sizeof(t));
ret = CcGetClientConfig(pc->RemoteClient, &t);
if (ret == ERR_NO_ERROR)
{
// Change the settings
t.NicDownOnDisconnect = true;
ret = CcSetClientConfig(pc->RemoteClient, &t);
}
if (ret == ERR_NO_ERROR)
{
// Success
}
if (ret != ERR_NO_ERROR)
{
// Error has occurred
CmdPrintError(c, ret);
}
// Release of the parameter list
FreeParamValueList(o);
return ret;
}
// Disable turning TUN interface up/down on client connect/disconnect
UINT PcTunDownOnDisconnectDisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{
LIST *o;
PC *pc = (PC *)param;
UINT ret = ERR_NO_ERROR;
CLIENT_CONFIG t;
// Get the parameter list
o = ParseCommandList(c, cmd_name, str, NULL, 0);
if (o == NULL)
{
return ERR_INVALID_PARAMETER;
}
// RPC call
Zero(&t, sizeof(t));
ret = CcGetClientConfig(pc->RemoteClient, &t);
if (ret == ERR_NO_ERROR)
{
// Change the settings
t.NicDownOnDisconnect = false;
ret = CcSetClientConfig(pc->RemoteClient, &t);
}
if (ret == ERR_NO_ERROR)
{
// Success
}
if (ret != ERR_NO_ERROR)
{
// Error has occurred
CmdPrintError(c, ret);
}
// Release of the parameter list
FreeParamValueList(o);
return ret;
}
// Get status of turning TUN interface up/down on client connect/disconnect
UINT PcTunDownOnDisconnectGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{
LIST *o;
PC *pc = (PC *)param;
UINT ret = ERR_NO_ERROR;
CLIENT_CONFIG t;
o = ParseCommandList(c, cmd_name, str, NULL, 0);
if (o == NULL)
{
return ERR_INVALID_PARAMETER;
}
// RPC call
Zero(&t, sizeof(t));
ret = CcGetClientConfig(pc->RemoteClient, &t);
if (ret == ERR_NO_ERROR)
{
wchar_t tmp[MAX_SIZE];
CT *ct = CtNewStandard();
CtInsert(ct, _UU("CMD_TUNDownOnDisconnectGet_COLUMN1"),
t.NicDownOnDisconnect ? _UU("SM_ACCESS_ENABLE") : _UU("SM_ACCESS_DISABLE"));
CtFree(ct, c);
}
if (ret != ERR_NO_ERROR)
{
// Error has occurred
CmdPrintError(c, ret);
}
// Release of the parameter list
FreeParamValueList(o);
return ret;
}
// Enable the maintenance function of the Internet connection
UINT PcKeepEnable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{

View File

@ -483,6 +483,9 @@ UINT PcAccountExport(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountImport(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcRemoteEnable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcRemoteDisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcTunDownOnDisconnectEnable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcTunDownOnDisconnectDisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcTunDownOnDisconnectGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcKeepEnable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcKeepDisable(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcKeepSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);

View File

@ -612,7 +612,7 @@ void StartLink(LINK *k)
pa->Param = (void *)k;
LockLink(k);
{
k->ClientSession = NewClientSession(k->Cedar, k->Option, k->Auth, pa);
k->ClientSession = NewClientSession(k->Cedar, k->Option, k->Auth, pa, NULL);
}
UnlockLink(k);
}

View File

@ -5385,6 +5385,14 @@ REDIRECTED:
PrintStatus(sess, _UU("STATUS_9"));
#ifdef OS_UNIX
// Set TUN up if session has NicDownOnDisconnect set
if (c->Session->NicDownOnDisconnect != NULL)
{
UnixVLanSetState(c->Session->ClientOption->DeviceName, true);
}
#endif
// Shift the connection to the tunneling mode
StartTunnelingMode(c);
s = NULL;

View File

@ -1381,6 +1381,13 @@ void CleanupSession(SESSION *s)
FreePacketAdapter(s->PacketAdapter);
}
#ifdef OS_UNIX
if (s->NicDownOnDisconnect != NULL && *s->NicDownOnDisconnect)
{
UnixVLanSetState(s->ClientOption->DeviceName, false);
}
#endif
if (s->OldTraffic != NULL)
{
FreeTraffic(s->OldTraffic);
@ -1529,6 +1536,13 @@ void ClientThread(THREAD *t, void *param)
CLog(s->Cedar->Client, "LC_CONNECT_ERROR", s->ClientOption->AccountName,
GetUniErrorStr(s->Err), s->Err);
#ifdef OS_UNIX
if (s->NicDownOnDisconnect != NULL && *s->NicDownOnDisconnect)
{
UnixVLanSetState(s->ClientOption->DeviceName, false);
}
#endif
if (s->LinkModeClient && s->Link != NULL)
{
HLog(s->Link->Hub, "LH_CONNECT_ERROR", s->ClientOption->AccountName,
@ -1953,7 +1967,7 @@ SESSION *NewRpcSessionEx2(CEDAR *cedar, CLIENT_OPTION *option, UINT *err, char *
}
// Create a client session
SESSION *NewClientSessionEx(CEDAR *cedar, CLIENT_OPTION *option, CLIENT_AUTH *auth, PACKET_ADAPTER *pa, ACCOUNT *account)
SESSION *NewClientSessionEx(CEDAR *cedar, CLIENT_OPTION *option, CLIENT_AUTH *auth, PACKET_ADAPTER *pa, ACCOUNT *account, bool *NicDownOnDisconnect)
{
SESSION *s;
THREAD *t;
@ -2081,6 +2095,8 @@ SESSION *NewClientSessionEx(CEDAR *cedar, CLIENT_OPTION *option, CLIENT_AUTH *au
s->ClientOption->NumRetry = 0;
}
s->NicDownOnDisconnect = NicDownOnDisconnect;
// Create a client thread
t = NewThread(ClientThread, (void *)s);
WaitThreadInit(t);
@ -2088,9 +2104,9 @@ SESSION *NewClientSessionEx(CEDAR *cedar, CLIENT_OPTION *option, CLIENT_AUTH *au
return s;
}
SESSION *NewClientSession(CEDAR *cedar, CLIENT_OPTION *option, CLIENT_AUTH *auth, PACKET_ADAPTER *pa)
SESSION *NewClientSession(CEDAR *cedar, CLIENT_OPTION *option, CLIENT_AUTH *auth, PACKET_ADAPTER *pa, bool *NicDownOnDisconnect)
{
return NewClientSessionEx(cedar, option, auth, pa, NULL);
return NewClientSessionEx(cedar, option, auth, pa, NULL, NicDownOnDisconnect);
}
// Get the session from the 32bit session key

View File

@ -324,6 +324,8 @@ struct SESSION
// Measures for D-Link bug
UINT64 LastDLinkSTPPacketSendTick; // Last D-Link STP packet transmission time
UCHAR LastDLinkSTPPacketDataHash[MD5_SIZE]; // Last D-Link STP packet hash
bool *NicDownOnDisconnect; // Pointer to client configuration parameter. NULL for non-clients.
};
// Password dialog
@ -399,8 +401,8 @@ struct UI_CHECKCERT
// Function prototype
SESSION *NewClientSessionEx(CEDAR *cedar, CLIENT_OPTION *option, CLIENT_AUTH *auth, PACKET_ADAPTER *pa, struct ACCOUNT *account);
SESSION *NewClientSession(CEDAR *cedar, CLIENT_OPTION *option, CLIENT_AUTH *auth, PACKET_ADAPTER *pa);
SESSION *NewClientSessionEx(CEDAR *cedar, CLIENT_OPTION *option, CLIENT_AUTH *auth, PACKET_ADAPTER *pa, struct ACCOUNT *account, bool *NicDownOnDisconnect);
SESSION *NewClientSession(CEDAR *cedar, CLIENT_OPTION *option, CLIENT_AUTH *auth, PACKET_ADAPTER *pa, bool *NicDownOnDisconnect);
SESSION *NewRpcSession(CEDAR *cedar, CLIENT_OPTION *option);
SESSION *NewRpcSessionEx(CEDAR *cedar, CLIENT_OPTION *option, UINT *err, char *client_str);
SESSION *NewRpcSessionEx2(CEDAR *cedar, CLIENT_OPTION *option, UINT *err, char *client_str, void *hWnd);

View File

@ -360,7 +360,7 @@ void FreeVLan(VLAN *v)
}
// Create a tap
VLAN *NewTap(char *name, char *mac_address)
VLAN *NewTap(char *name, char *mac_address, bool create_up)
{
int fd;
VLAN *v;
@ -370,7 +370,7 @@ VLAN *NewTap(char *name, char *mac_address)
return NULL;
}
fd = UnixCreateTapDeviceEx(name, "tap", mac_address);
fd = UnixCreateTapDeviceEx(name, "tap", mac_address, create_up);
if (fd == -1)
{
return NULL;
@ -423,13 +423,25 @@ VLAN *NewVLan(char *instance_name, VLAN_PARAM *param)
return v;
}
// Generate TUN interface name
void GenerateTunName(char *name, char *prefix, char *tun_name, size_t tun_name_len)
{
char instance_name_lower[MAX_SIZE];
// Generate the device name
StrCpy(instance_name_lower, sizeof(instance_name_lower), name);
Trim(instance_name_lower);
StrLower(instance_name_lower);
Format(tun_name, tun_name_len, "%s_%s", prefix, instance_name_lower);
tun_name[15] = 0;
}
// Create a tap device
int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address)
int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address, bool create_up)
{
int fd;
struct ifreq ifr;
char eth_name[MAX_SIZE];
char instance_name_lower[MAX_SIZE];
struct sockaddr sa;
char *tap_name = TAP_FILENAME_1;
int s;
@ -442,13 +454,7 @@ int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address)
return -1;
}
// Generate the device name
StrCpy(instance_name_lower, sizeof(instance_name_lower), name);
Trim(instance_name_lower);
StrLower(instance_name_lower);
Format(eth_name, sizeof(eth_name), "%s_%s", prefix, instance_name_lower);
eth_name[15] = 0;
GenerateTunName(name, prefix, eth_name, sizeof(eth_name));
// Open the tun / tap
#ifndef UNIX_MACOS
@ -531,8 +537,11 @@ int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address)
StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), eth_name);
ioctl(s, SIOCGIFFLAGS, &ifr);
ifr.ifr_flags |= IFF_UP;
ioctl(s, SIOCSIFFLAGS, &ifr);
if (create_up)
{
ifr.ifr_flags |= IFF_UP;
ioctl(s, SIOCSIFFLAGS, &ifr);
}
close(s);
}
@ -560,8 +569,11 @@ int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address)
StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), macos_eth_name);
ioctl(s, SIOCGIFFLAGS, &ifr);
ifr.ifr_flags |= IFF_UP;
ioctl(s, SIOCSIFFLAGS, &ifr);
if (create_up)
{
ifr.ifr_flags |= IFF_UP;
ioctl(s, SIOCSIFFLAGS, &ifr);
}
close(s);
}
@ -637,9 +649,9 @@ int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address)
return fd;
}
int UnixCreateTapDevice(char *name, UCHAR *mac_address)
int UnixCreateTapDevice(char *name, UCHAR *mac_address, bool create_up)
{
return UnixCreateTapDeviceEx(name, "vpn", mac_address);
return UnixCreateTapDeviceEx(name, "vpn", mac_address, create_up);
}
// Close the tap device
@ -696,7 +708,7 @@ void UnixVLanInit()
}
// Create a VLAN
bool UnixVLanCreateEx(char *name, char *prefix, UCHAR *mac_address)
bool UnixVLanCreateEx(char *name, char *prefix, UCHAR *mac_address, bool create_up)
{
// Validate arguments
char tmp[MAX_SIZE];
@ -727,7 +739,7 @@ bool UnixVLanCreateEx(char *name, char *prefix, UCHAR *mac_address)
}
// Create a tap device
fd = UnixCreateTapDeviceEx(name, prefix, mac_address);
fd = UnixCreateTapDeviceEx(name, prefix, mac_address, create_up);
if (fd == -1)
{
// Failure to create
@ -745,9 +757,63 @@ bool UnixVLanCreateEx(char *name, char *prefix, UCHAR *mac_address)
return true;
}
bool UnixVLanCreate(char *name, UCHAR *mac_address)
bool UnixVLanCreate(char *name, UCHAR *mac_address, bool create_up)
{
return UnixVLanCreateEx(name, "vpn", mac_address);
return UnixVLanCreateEx(name, "vpn", mac_address, create_up);
}
// Set a VLAN up/down
bool UnixVLanSetState(char* name, bool state_up)
{
#ifdef UNIX_LINUX
UNIX_VLAN_LIST *t, tt;
struct ifreq ifr;
int s;
char eth_name[MAX_SIZE];
LockList(unix_vlan);
{
int result;
// Find a device with the same name
Zero(&tt, sizeof(tt));
StrCpy(tt.Name, sizeof(tt.Name), name);
t = Search(unix_vlan, &tt);
if (t == NULL)
{
// No such device
UnlockList(unix_vlan);
return false;
}
GenerateTunName(name, "vpn", eth_name, sizeof(eth_name));
Zero(&ifr, sizeof(ifr));
StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), eth_name);
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == -1)
{
// Failed to create socket
UnlockList(unix_vlan);
return false;
}
ioctl(s, SIOCGIFFLAGS, &ifr);
if (state_up)
{
ifr.ifr_flags |= IFF_UP;
}
else
{
ifr.ifr_flags &= ~IFF_UP;
}
result = ioctl(s, SIOCSIFFLAGS, &ifr);
close(s);
}
UnlockList(unix_vlan);
#endif // UNIX_LINUX
return true;
}
// Enumerate VLANs

View File

@ -129,7 +129,7 @@ struct VLAN
// Function prototype
VLAN *NewVLan(char *instance_name, VLAN_PARAM *param);
VLAN *NewTap(char *name, char *mac_address);
VLAN *NewTap(char *name, char *mac_address, bool create_up);
void FreeVLan(VLAN *v);
CANCEL *VLanGetCancel(VLAN *v);
bool VLanGetNextPacket(VLAN *v, void **buf, UINT *size);
@ -154,15 +154,16 @@ struct UNIX_VLAN_LIST
int fd; // fd
};
int UnixCreateTapDevice(char *name, UCHAR *mac_address);
int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address);
int UnixCreateTapDevice(char *name, UCHAR *mac_address, bool create_up);
int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address, bool create_up);
void UnixCloseTapDevice(int fd);
void UnixVLanInit();
void UnixVLanFree();
bool UnixVLanCreate(char *name, UCHAR *mac_address);
bool UnixVLanCreateEx(char *name, char *prefix, UCHAR *mac_address);
bool UnixVLanCreate(char *name, UCHAR *mac_address, bool create_up);
bool UnixVLanCreateEx(char *name, char *prefix, UCHAR *mac_address, bool create_up);
TOKEN_LIST *UnixVLanEnum();
void UnixVLanDelete(char *name);
bool UnixVLanSetState(char* name, bool state_up);
int UnixVLanGet(char *name);
int UnixCompareVLan(void *p1, void *p2);