2017-11-06 13:50:20 -08:00
|
|
|
/*
|
2021-02-04 11:03:55 -08:00
|
|
|
* Copyright (c)2013-2021 ZeroTier, Inc.
|
2017-11-06 13:50:20 -08:00
|
|
|
*
|
2020-04-13 23:38:06 -07:00
|
|
|
* Use of this software is governed by the Business Source License included
|
|
|
|
|
* in the LICENSE.TXT file in the project's root directory.
|
2017-11-06 13:50:20 -08:00
|
|
|
*
|
2021-04-22 11:20:04 -07:00
|
|
|
* Change Date: 2026-01-01
|
2017-11-06 13:50:20 -08:00
|
|
|
*
|
2020-04-13 23:38:06 -07:00
|
|
|
* On the date above, in accordance with the Business Source License, use
|
|
|
|
|
* of this software will be governed by version 2.0 of the Apache License.
|
2017-11-06 13:50:20 -08:00
|
|
|
*/
|
2020-04-13 23:38:06 -07:00
|
|
|
/****/
|
2017-11-06 13:50:20 -08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @file
|
|
|
|
|
*
|
2021-04-22 11:20:04 -07:00
|
|
|
* Header for virtual Ethernet tap device and combined network stack driver
|
2017-11-06 13:50:20 -08:00
|
|
|
*/
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
#ifndef ZTS_VIRTUAL_TAP_HPP
|
|
|
|
|
#define ZTS_VIRTUAL_TAP_HPP
|
2017-11-06 13:50:20 -08:00
|
|
|
|
2020-05-01 19:15:38 -07:00
|
|
|
#include "lwip/err.h"
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
#define ZTS_LWIP_THREAD_NAME "ZTNetworkStackThread"
|
|
|
|
|
#define VTAP_NAME_LEN 64
|
2017-11-21 15:53:31 -08:00
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
#include "Events.hpp"
|
2020-05-01 19:15:38 -07:00
|
|
|
#include "MAC.hpp"
|
2017-11-06 13:50:20 -08:00
|
|
|
#include "Phy.hpp"
|
2019-01-14 12:01:29 -08:00
|
|
|
#include "Thread.hpp"
|
2017-11-06 13:50:20 -08:00
|
|
|
|
2019-01-14 12:01:29 -08:00
|
|
|
namespace ZeroTier {
|
2017-11-06 13:50:20 -08:00
|
|
|
|
2019-01-14 12:01:29 -08:00
|
|
|
class Mutex;
|
2020-05-01 19:15:38 -07:00
|
|
|
class MAC;
|
|
|
|
|
class MulticastGroup;
|
|
|
|
|
struct InetAddress;
|
2017-11-06 13:50:20 -08:00
|
|
|
|
|
|
|
|
/**
|
2021-04-22 11:20:04 -07:00
|
|
|
* Virtual tap device. ZeroTier will create one per joined network. It will
|
|
|
|
|
* then be destroyed upon leaving the network.
|
2017-11-06 13:50:20 -08:00
|
|
|
*/
|
2021-04-17 23:46:21 -07:00
|
|
|
class VirtualTap {
|
|
|
|
|
friend class Phy<VirtualTap*>;
|
2017-11-06 13:50:20 -08:00
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
public:
|
2017-11-06 13:50:20 -08:00
|
|
|
VirtualTap(
|
2021-04-17 23:46:21 -07:00
|
|
|
const char* homePath,
|
|
|
|
|
const MAC& mac,
|
|
|
|
|
unsigned int mtu,
|
|
|
|
|
unsigned int metric,
|
2021-04-22 11:20:04 -07:00
|
|
|
uint64_t net_id,
|
2021-04-17 23:46:21 -07:00
|
|
|
const char* friendlyName,
|
|
|
|
|
void (*handler)(
|
|
|
|
|
void*,
|
|
|
|
|
void*,
|
|
|
|
|
uint64_t,
|
|
|
|
|
const MAC&,
|
|
|
|
|
const MAC&,
|
|
|
|
|
unsigned int,
|
|
|
|
|
unsigned int,
|
|
|
|
|
const void*,
|
|
|
|
|
unsigned int),
|
|
|
|
|
void* arg);
|
2017-11-06 13:50:20 -08:00
|
|
|
|
|
|
|
|
~VirtualTap();
|
|
|
|
|
|
|
|
|
|
void setEnabled(bool en);
|
|
|
|
|
bool enabled() const;
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
/**
|
|
|
|
|
* System to ingest events from this class and emit them to the user
|
|
|
|
|
*/
|
|
|
|
|
Events* _events;
|
|
|
|
|
|
2019-02-14 17:27:16 -08:00
|
|
|
/**
|
|
|
|
|
* Mutex for protecting IP address container for this tap.
|
|
|
|
|
*/
|
2021-04-22 11:20:04 -07:00
|
|
|
Mutex _ips_m; // Public because we want it accessible by the driver
|
|
|
|
|
// layer
|
|
|
|
|
|
|
|
|
|
void setUserEventSystem(Events* events);
|
2019-02-14 17:27:16 -08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return whether this tap has been assigned an IPv4 address.
|
|
|
|
|
*/
|
|
|
|
|
bool hasIpv4Addr();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return whether this tap has been assigned an IPv6 address.
|
|
|
|
|
*/
|
|
|
|
|
bool hasIpv6Addr();
|
|
|
|
|
|
2017-11-06 13:50:20 -08:00
|
|
|
/**
|
2021-04-22 11:20:04 -07:00
|
|
|
* Adds an address to the user-space stack interface associated with
|
|
|
|
|
* this VirtualTap
|
2017-11-06 13:50:20 -08:00
|
|
|
* - Starts VirtualTap main thread ONLY if successful
|
|
|
|
|
*/
|
2021-04-17 23:46:21 -07:00
|
|
|
bool addIp(const InetAddress& ip);
|
2017-11-06 13:50:20 -08:00
|
|
|
|
|
|
|
|
/**
|
2021-04-22 11:20:04 -07:00
|
|
|
* Removes an address from the user-space stack interface associated
|
|
|
|
|
* with this VirtualTap
|
2017-11-06 13:50:20 -08:00
|
|
|
*/
|
2021-04-17 23:46:21 -07:00
|
|
|
bool removeIp(const InetAddress& ip);
|
2017-11-06 13:50:20 -08:00
|
|
|
|
|
|
|
|
/**
|
2020-05-01 19:15:38 -07:00
|
|
|
* Presents data to the user-space stack
|
2017-11-06 13:50:20 -08:00
|
|
|
*/
|
2021-04-17 23:46:21 -07:00
|
|
|
void
|
|
|
|
|
put(const MAC& from, const MAC& to, unsigned int etherType, const void* data, unsigned int len);
|
2017-11-06 13:50:20 -08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Scan multicast groups
|
|
|
|
|
*/
|
2021-04-17 23:46:21 -07:00
|
|
|
void
|
|
|
|
|
scanMulticastGroups(std::vector<MulticastGroup>& added, std::vector<MulticastGroup>& removed);
|
2017-11-06 13:50:20 -08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Set MTU
|
|
|
|
|
*/
|
|
|
|
|
void setMtu(unsigned int mtu);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Calls main network stack loops
|
|
|
|
|
*/
|
2021-04-17 23:46:21 -07:00
|
|
|
void threadMain() throw();
|
2017-11-06 13:50:20 -08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* For moving data onto the ZeroTier virtual wire
|
|
|
|
|
*/
|
2021-04-17 23:46:21 -07:00
|
|
|
void (*_handler)(
|
|
|
|
|
void*,
|
|
|
|
|
void*,
|
|
|
|
|
uint64_t,
|
|
|
|
|
const MAC&,
|
|
|
|
|
const MAC&,
|
|
|
|
|
unsigned int,
|
|
|
|
|
unsigned int,
|
|
|
|
|
const void*,
|
|
|
|
|
unsigned int);
|
|
|
|
|
|
|
|
|
|
void* netif4 = NULL;
|
|
|
|
|
void* netif6 = NULL;
|
2019-01-31 03:08:48 -08:00
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
// The last time that this virtual tap received a network config update
|
|
|
|
|
// from the core
|
2019-01-31 03:08:48 -08:00
|
|
|
uint64_t _lastConfigUpdateTime = 0;
|
|
|
|
|
|
|
|
|
|
void lastConfigUpdate(uint64_t lastConfigUpdateTime);
|
|
|
|
|
|
|
|
|
|
int _networkStatus = 0;
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
char vtap_full_name[VTAP_NAME_LEN] = { 0 };
|
2017-11-06 13:50:20 -08:00
|
|
|
|
2019-01-14 12:01:29 -08:00
|
|
|
std::vector<InetAddress> ips() const;
|
|
|
|
|
std::vector<InetAddress> _ips;
|
2017-11-06 13:50:20 -08:00
|
|
|
|
|
|
|
|
std::string _homePath;
|
2021-04-17 23:46:21 -07:00
|
|
|
void* _arg;
|
2017-11-06 13:50:20 -08:00
|
|
|
volatile bool _initialized;
|
|
|
|
|
volatile bool _enabled;
|
|
|
|
|
volatile bool _run;
|
2019-01-14 12:01:29 -08:00
|
|
|
MAC _mac;
|
2017-11-06 13:50:20 -08:00
|
|
|
unsigned int _mtu;
|
2021-04-22 11:20:04 -07:00
|
|
|
uint64_t _net_id;
|
2021-04-17 23:46:21 -07:00
|
|
|
PhySocket* _unixListenSocket;
|
|
|
|
|
Phy<VirtualTap*> _phy;
|
2017-11-06 13:50:20 -08:00
|
|
|
|
|
|
|
|
Thread _thread;
|
2019-01-14 12:01:29 -08:00
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int _shutdownSignalPipe[2] = { 0 };
|
2017-11-06 13:50:20 -08:00
|
|
|
|
|
|
|
|
std::vector<MulticastGroup> _multicastGroups;
|
|
|
|
|
Mutex _multicastGroups_m;
|
2019-01-14 12:01:29 -08:00
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
// Not used in this implementation //
|
|
|
|
|
//----------------------------------------------------------------------------//
|
2017-11-06 13:50:20 -08:00
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
void phyOnDatagram(
|
|
|
|
|
PhySocket* sock,
|
|
|
|
|
void** uptr,
|
|
|
|
|
const struct sockaddr* local_address,
|
|
|
|
|
const struct sockaddr* from,
|
|
|
|
|
void* data,
|
|
|
|
|
unsigned long len);
|
|
|
|
|
void phyOnTcpConnect(PhySocket* sock, void** uptr, bool success);
|
|
|
|
|
void phyOnTcpAccept(
|
|
|
|
|
PhySocket* sockL,
|
|
|
|
|
PhySocket* sockN,
|
|
|
|
|
void** uptrL,
|
|
|
|
|
void** uptrN,
|
|
|
|
|
const struct sockaddr* from);
|
|
|
|
|
void phyOnTcpClose(PhySocket* sock, void** uptr);
|
|
|
|
|
void phyOnTcpData(PhySocket* sock, void** uptr, void* data, unsigned long len);
|
|
|
|
|
void phyOnTcpWritable(PhySocket* sock, void** uptr);
|
|
|
|
|
void phyOnUnixClose(PhySocket* sock, void** uptr);
|
2017-11-06 13:50:20 -08:00
|
|
|
};
|
|
|
|
|
|
2020-05-01 19:15:38 -07:00
|
|
|
/**
|
|
|
|
|
* @brief Return whether a given netif's NETIF_FLAG_UP flag is set
|
|
|
|
|
*
|
|
|
|
|
* @usage This is a convenience function to encapsulate a macro
|
|
|
|
|
*/
|
2021-04-17 23:46:21 -07:00
|
|
|
bool _lwip_is_netif_up(void* netif);
|
2020-05-01 19:15:38 -07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Increase the delay multiplier for the main driver loop
|
|
|
|
|
*
|
2021-04-22 11:20:04 -07:00
|
|
|
* @usage This should be called when we know the stack won't be used by any
|
|
|
|
|
* virtual taps
|
2020-05-01 19:15:38 -07:00
|
|
|
*/
|
|
|
|
|
void _lwip_hibernate_driver();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Decrease the delay multiplier for the main driver loop
|
|
|
|
|
*
|
|
|
|
|
* @usage This should be called when at least one virtual tap is active
|
|
|
|
|
*/
|
|
|
|
|
void _lwip_wake_driver();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns whether the lwIP network stack is up and ready to process traffic
|
|
|
|
|
*/
|
|
|
|
|
bool _lwip_is_up();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Initialize network stack semaphores, threads, and timers.
|
|
|
|
|
*
|
2021-04-22 11:20:04 -07:00
|
|
|
* @usage This is called during the initial setup of each VirtualTap but is
|
|
|
|
|
* only allowed to execute once
|
2020-05-01 19:15:38 -07:00
|
|
|
*/
|
|
|
|
|
void _lwip_driver_init();
|
|
|
|
|
|
|
|
|
|
/**
|
2021-04-22 11:20:04 -07:00
|
|
|
* @brief Shutdown the stack as completely as possible (not officially
|
|
|
|
|
* supported by lwIP)
|
2020-05-01 19:15:38 -07:00
|
|
|
*
|
2021-04-22 11:20:04 -07:00
|
|
|
* @usage This is to be called after it is determined that no further
|
|
|
|
|
* network activity will take place. The tcpip thread will be stopped, all
|
|
|
|
|
* interfaces will be brought down and all resources will be deallocated. A
|
|
|
|
|
* full application restart will be required to bring the stack back online.
|
2020-05-01 19:15:38 -07:00
|
|
|
*/
|
|
|
|
|
void _lwip_driver_shutdown();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Requests that a netif be brought down and removed.
|
|
|
|
|
*/
|
2021-04-17 23:46:21 -07:00
|
|
|
void _lwip_remove_netif(void* netif);
|
2020-05-01 19:15:38 -07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Starts DHCP timers
|
|
|
|
|
*/
|
2021-04-17 23:46:21 -07:00
|
|
|
void _lwip_start_dhcp(void* netif);
|
2020-05-01 19:15:38 -07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Called when the status of a netif changes:
|
|
|
|
|
* - Interface is up/down (ZTS_EVENT_NETIF_UP, ZTS_EVENT_NETIF_DOWN)
|
|
|
|
|
* - Address changes while up (ZTS_EVENT_NETIF_NEW_ADDRESS)
|
|
|
|
|
*/
|
|
|
|
|
#if LWIP_NETIF_STATUS_CALLBACK
|
2021-04-17 23:46:21 -07:00
|
|
|
static void _netif_status_callback(struct netif* netif);
|
2020-05-01 19:15:38 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Called when a netif is removed (ZTS_EVENT_NETIF_INTERFACE_REMOVED)
|
|
|
|
|
*/
|
|
|
|
|
#if LWIP_NETIF_REMOVE_CALLBACK
|
2021-04-17 23:46:21 -07:00
|
|
|
static void _netif_remove_callback(struct netif* netif);
|
2020-05-01 19:15:38 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/**
|
2021-04-17 23:46:21 -07:00
|
|
|
* @brief Called when a link is brought up or down (ZTS_EVENT_NETIF_LINK_UP,
|
|
|
|
|
* ZTS_EVENT_NETIF_LINK_DOWN)
|
2020-05-01 19:15:38 -07:00
|
|
|
*/
|
|
|
|
|
#if LWIP_NETIF_LINK_CALLBACK
|
2021-04-17 23:46:21 -07:00
|
|
|
static void _netif_link_callback(struct netif* netif);
|
2020-05-01 19:15:38 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Set up an interface in the network stack for the VirtualTap.
|
|
|
|
|
*
|
2021-04-22 11:20:04 -07:00
|
|
|
* @param tapref Reference to VirtualTap that will be responsible for
|
|
|
|
|
* sending and receiving data
|
2020-05-01 19:15:38 -07:00
|
|
|
* @param ip Virtual IP address for this ZeroTier VirtualTap interface
|
|
|
|
|
*/
|
2021-04-17 23:46:21 -07:00
|
|
|
void _lwip_init_interface(void* tapref, const InetAddress& ip);
|
2020-05-01 19:15:38 -07:00
|
|
|
|
2020-05-30 18:29:04 -07:00
|
|
|
/**
|
|
|
|
|
* @brief Remove an assigned address from an lwIP netif
|
|
|
|
|
*
|
|
|
|
|
* @param tapref Reference to VirtualTap
|
|
|
|
|
* @param ip Virtual IP address to remove from this interface
|
|
|
|
|
*/
|
2021-04-17 23:46:21 -07:00
|
|
|
void _lwip_remove_address_from_netif(void* tapref, const InetAddress& ip);
|
2020-05-30 18:29:04 -07:00
|
|
|
|
2020-05-01 19:15:38 -07:00
|
|
|
/**
|
2021-04-22 11:20:04 -07:00
|
|
|
* @brief Called from the stack, outbound Ethernet frames from the network
|
|
|
|
|
* stack enter the ZeroTier virtual wire here.
|
2020-05-01 19:15:38 -07:00
|
|
|
*
|
2021-04-22 11:20:04 -07:00
|
|
|
* @usage This shall only be called from the stack or the stack driver. Not
|
|
|
|
|
* the application thread.
|
|
|
|
|
* @param netif Transmits an outgoing Ethernet frame from the network stack
|
|
|
|
|
* onto the ZeroTier virtual wire
|
2020-05-01 19:15:38 -07:00
|
|
|
* @param p A pointer to the beginning of a chain pf struct pbufs
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
2021-04-17 23:46:21 -07:00
|
|
|
err_t _lwip_eth_tx(struct netif* netif, struct pbuf* p);
|
2020-05-01 19:15:38 -07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Receives incoming Ethernet frames from the ZeroTier virtual wire
|
|
|
|
|
*
|
2021-04-22 11:20:04 -07:00
|
|
|
* @usage This shall be called from the VirtualTap's I/O thread (via
|
|
|
|
|
* VirtualTap::put())
|
2020-05-01 19:15:38 -07:00
|
|
|
* @param tap Pointer to VirtualTap from which this data comes
|
|
|
|
|
* @param from Origin address (virtual ZeroTier hardware address)
|
2021-04-22 11:20:04 -07:00
|
|
|
* @param to Intended destination address (virtual ZeroTier hardware
|
|
|
|
|
* address)
|
2020-05-01 19:15:38 -07:00
|
|
|
* @param etherType Protocol type
|
|
|
|
|
* @param data Pointer to Ethernet frame
|
|
|
|
|
* @param len Length of Ethernet frame
|
|
|
|
|
*/
|
2021-04-17 23:46:21 -07:00
|
|
|
void _lwip_eth_rx(
|
|
|
|
|
VirtualTap* tap,
|
|
|
|
|
const MAC& from,
|
|
|
|
|
const MAC& to,
|
|
|
|
|
unsigned int etherType,
|
|
|
|
|
const void* data,
|
|
|
|
|
unsigned int len);
|
2017-11-06 13:50:20 -08:00
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
} // namespace ZeroTier
|
2020-05-01 19:15:38 -07:00
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
#endif // _H
|