Stubbed out experimental raw drivers

This commit is contained in:
Joseph Henry
2017-09-29 15:37:50 -07:00
parent bac18b8d7c
commit c0aac699e7
5 changed files with 392 additions and 63 deletions

View File

@@ -36,14 +36,21 @@
#include "MAC.hpp"
#include "InetAddress.hpp"
#include "Defs.h"
#include "Mutex.hpp"
/**
* @brief Initialize network stack semaphores, threads, and timers.
*
* @usage This is called during the initial setup of each VirtualTap but is only allowed to execute once
* @return
*/
void lwip_driver_init();
void general_lwip_init_interface(void *tapref, struct netif *interface, const char *name, const ZeroTier::MAC &mac,
const ZeroTier::InetAddress &addr, const ZeroTier::InetAddress &nm, const ZeroTier::InetAddress &gw);
void general_turn_on_interface(struct netif *interface);
/**
* @brief Set up an interface in the network stack for the VirtualTap.
*

View File

@@ -100,11 +100,13 @@ namespace ZeroTier {
snprintf(vtap_full_name, sizeof(vtap_full_name), "libzt%d-%lx", devno++, _nwid);
_dev = vtap_full_name;
DEBUG_INFO("set VirtualTap interface name to: %s", _dev.c_str());
// set virtual tap interface name (abbreviated)
memset(vtap_abbr_name, 0, sizeof(vtap_abbr_name));
snprintf(vtap_abbr_name, sizeof(vtap_abbr_name), "libzt%d", devno);
#if defined(STACK_LWIP)
// initialize network stacks
lwip_driver_init();
#endif
// start vtap thread and stack I/O loops
_thread = Thread::start(this);
}
@@ -129,18 +131,16 @@ namespace ZeroTier {
bool VirtualTap::registerIpWithStack(const InetAddress &ip)
{
DEBUG_EXTRA();
lwip_driver_init();
#if defined(STACK_LWIP)
lwip_init_interface((void*)this, this->_mac, ip);
#endif
return true;
}
bool VirtualTap::addIp(const InetAddress &ip)
{
int err = false;
char ipbuf[INET6_ADDRSTRLEN];
DEBUG_EXTRA("addIp (%s)", ip.toString(ipbuf));
DEBUG_EXTRA("addr=%s", ip.toString(ipbuf));
Mutex::Lock _l(_ips_m);
if (registerIpWithStack(ip)) {
if (std::find(_ips.begin(),_ips.end(),ip) == _ips.end()) {
@@ -149,7 +149,7 @@ namespace ZeroTier {
}
return true;
}
return err;
return false;
}
bool VirtualTap::removeIp(const InetAddress &ip)
@@ -179,7 +179,9 @@ namespace ZeroTier {
void VirtualTap::put(const MAC &from,const MAC &to,unsigned int etherType,
const void *data,unsigned int len)
{
#if defined(STACK_LWIP)
lwip_eth_rx(this, from, to, etherType, data, len);
#endif
}
std::string VirtualTap::deviceName() const
@@ -237,7 +239,6 @@ namespace ZeroTier {
void VirtualTap::threadMain()
throw()
{
DEBUG_EXTRA();
while (true) {
_phy.poll(ZT_PHY_POLL_INTERVAL);
Housekeeping();
@@ -259,17 +260,49 @@ namespace ZeroTier {
DEBUG_EXTRA();
}
bool VirtualTap::routeAdd(const InetAddress &addr, const InetAddress &nm, const InetAddress &gw)
bool VirtualTap::routeAdd(const InetAddress &ip, const InetAddress &nm, const InetAddress &gw)
{
bool err = false;
DEBUG_EXTRA();
#if defined(STACK_LWIP)
//general_lwip_init_interface(this, NULL, "n1", _mac, ip, nm, gw);
//general_turn_on_interface(NULL);
#endif
#if defined(STACK_PICO)
if (picostack) {
return picostack->pico_route_add(this, ip, nm, gw, 0);
} else {
handle_general_failure();
return false;
}
#endif
#if defined(NO_STACK)
// nothing to do
#endif
return err;
}
bool VirtualTap::routeDelete(const InetAddress &addr, const InetAddress &nm)
bool VirtualTap::routeDelete(const InetAddress &ip, const InetAddress &nm)
{
bool err = false;
DEBUG_EXTRA();
#if defined(STACK_LWIP)
//general_lwip_init_interface(this, NULL, "n1", _mac, ip, nm, gw);
//general_turn_on_interface(NULL);
#endif
#if defined(STACK_PICO)
if (picostack) {
return picostack->pico_route_del(this, ip, nm, 0);
} else {
handle_general_failure();
return false;
}
#endif
#if defined(NO_STACK)
// nothing to do
#endif
return err;
}
void VirtualTap::addVirtualSocket()
{
@@ -369,7 +402,7 @@ namespace ZeroTier {
Mutex::Lock _l(_tcpconns_m);
std::time_t current_ts = std::time(nullptr);
if (current_ts > last_housekeeping_ts + ZT_HOUSEKEEPING_INTERVAL) {
DEBUG_EXTRA();
// DEBUG_EXTRA();
// update managed routes (add/del from network stacks)
ZeroTier::OneService *service = ((ZeroTier::OneService *)zt1ServiceRef);
if (service) {

View File

@@ -143,12 +143,12 @@ namespace ZeroTier {
/**
* Adds a route to the virtual tap
*/
bool routeAdd(const InetAddress &addr, const InetAddress &nm, const InetAddress &gw);
bool routeAdd(const InetAddress &ip, const InetAddress &nm, const InetAddress &gw);
/**
* Deletes a route from the virtual tap
*/
bool routeDelete(const InetAddress &addr, const InetAddress &nm);
bool routeDelete(const InetAddress &ip, const InetAddress &nm);
/**
* Assign a VirtualSocket to the VirtualTap

View File

@@ -32,9 +32,14 @@
#include <cstring>
#if defined(STACK_LWIP)
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "lwip/ip_addr.h"
#endif
#if defined(NO_STACK)
#include <sys/socket.h>
#endif
#include "libzt.h"
@@ -42,6 +47,7 @@
extern "C" {
#endif
#if defined(STACK_LWIP)
void sys2lwip(int fd, const struct sockaddr *orig, struct sockaddr *modified) {
/* Inelegant fix for lwIP 'sequential' API address error check (in sockets.c). For some reason
@@ -76,183 +82,409 @@ void sys2lwip(int fd, const struct sockaddr *orig, struct sockaddr *modified) {
#endif
}
}
#endif // STACK_LWIP
int zts_socket(int socket_family, int socket_type, int protocol)
{
int err = -1;
DEBUG_EXTRA("family=%d, type=%d, proto=%d", socket_family, socket_type, protocol);
return lwip_socket(socket_family, socket_type, protocol);
#if defined(STACK_LWIP)
err = lwip_socket(socket_family, socket_type, protocol);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
int zts_connect(int fd, const struct sockaddr *addr, socklen_t addrlen)
{
int err = -1;
DEBUG_EXTRA("fd=%d",fd);
#if defined(STACK_LWIP)
struct sockaddr_storage ss;
sys2lwip(fd, addr, (struct sockaddr*)&ss);
return lwip_connect(fd, (struct sockaddr*)&ss, addrlen);
err = lwip_connect(fd, (struct sockaddr*)&ss, addrlen);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
int zts_bind(int fd, const struct sockaddr *addr, socklen_t addrlen)
{
int err = -1;
DEBUG_EXTRA("fd=%d", fd);
#if defined(STACK_LWIP)
struct sockaddr_storage ss;
sys2lwip(fd, addr, (struct sockaddr*)&ss);
return lwip_bind(fd, (struct sockaddr*)&ss, addrlen);
err = lwip_bind(fd, (struct sockaddr*)&ss, addrlen);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
int zts_listen(int fd, int backlog)
{
int err = -1;
DEBUG_EXTRA("fd=%d", fd);
return lwip_listen(fd, backlog);
#if defined(STACK_LWIP)
err = lwip_listen(fd, backlog);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
int zts_accept(int fd, struct sockaddr *addr, socklen_t *addrlen)
{
int err = -1;
DEBUG_EXTRA("fd=%d", fd);
return lwip_accept(fd, addr, addrlen);
#if defined(STACK_LWIP)
err = lwip_accept(fd, addr, addrlen);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
#if defined(__linux__)
int zts_accept4(int fd, struct sockaddr *addr, socklen_t *addrlen, int flags)
{
int err = -1;
DEBUG_EXTRA("fd=%d", fd);
return zts_accept(fd, addr, addrlen);
#if defined(STACK_LWIP)
err = zts_accept(fd, addr, addrlen);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
#endif
int zts_setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
{
int err = -1;
DEBUG_EXTRA("fd=%d, level=%d, optname=%d", fd, level, optname);
return lwip_setsockopt(fd, level, optname, optval, optlen);
#if defined(STACK_LWIP)
err = lwip_setsockopt(fd, level, optname, optval, optlen);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
int zts_getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen)
{
int err = -1;
DEBUG_EXTRA("fd=%d, level=%d, optname=%d", fd, level, optname);
return lwip_getsockopt(fd, level, optname, optval, optlen);
#if defined(STACK_LWIP)
err = lwip_getsockopt(fd, level, optname, optval, optlen);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
int zts_getsockname(int fd, struct sockaddr *addr, socklen_t *addrlen)
{
int err = -1;
DEBUG_EXTRA("fd=%p", fd);
return lwip_getsockname(fd, addr, addrlen);
#if defined(STACK_LWIP)
err = lwip_getsockname(fd, addr, addrlen);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
int zts_getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen)
{
int err = -1;
DEBUG_EXTRA("fd=%d", fd);
return lwip_getpeername(fd, addr, addrlen);
#if defined(STACK_LWIP)
err = lwip_getpeername(fd, addr, addrlen);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
int zts_gethostname(char *name, size_t len)
{
DEBUG_EXTRA();
return -1;
int err = -1;
#if defined(STACK_LWIP)
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
int zts_sethostname(const char *name, size_t len)
{
DEBUG_EXTRA();
return -1;
int err = -1;
#if defined(STACK_LWIP)
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
int zts_close(int fd)
{
int err = -1;
DEBUG_EXTRA("fd=%d", fd);
return lwip_close(fd);
#if defined(STACK_LWIP)
err = lwip_close(fd);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
int zts_poll(struct pollfd *fds, nfds_t nfds, int timeout)
{
int err = -1;
#if defined(STACK_LWIP)
DEBUG_ERROR("warning, this is not implemented");
return poll(fds, nfds, timeout);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
int zts_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
int zts_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *timeout)
{
int err = -1;
//DEBUG_EXTRA();
return lwip_select(nfds, readfds, writefds, exceptfds, timeout);
#if defined(STACK_LWIP)
err = lwip_select(nfds, readfds, writefds, exceptfds, timeout);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
int zts_fcntl(int fd, int cmd, int flags)
{
int err = -1;
DEBUG_EXTRA("fd=%p, cmd=%d, flags=%d", cmd, flags);
#if defined(STACK_LWIP)
// translation required since lwIP uses different flag values
int translated_flags = 0;
if (flags == 2048) {
translated_flags = 1;
}
return lwip_fcntl(fd, cmd, translated_flags);
err = lwip_fcntl(fd, cmd, translated_flags);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
int zts_ioctl(int fd, unsigned long request, void *argp)
{
int err = -1;
DEBUG_EXTRA("fd=%d, req=%d", fd, request);
return lwip_ioctl(fd, request, argp);
#if defined(STACK_LWIP)
err = lwip_ioctl(fd, request, argp);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
ssize_t zts_sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen)
ssize_t zts_sendto(int fd, const void *buf, size_t len, int flags,
const struct sockaddr *addr, socklen_t addrlen)
{
int err = -1;
DEBUG_TRANS("fd=%d, len=%d", fd, len);
#if defined(STACK_LWIP)
struct sockaddr_storage ss;
sys2lwip(fd, addr, (struct sockaddr*)&ss);
return lwip_sendto(fd, buf, len, flags, (struct sockaddr*)&ss, addrlen);
err = lwip_sendto(fd, buf, len, flags, (struct sockaddr*)&ss, addrlen);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
ssize_t zts_send(int fd, const void *buf, size_t len, int flags)
{
int err = -1;
DEBUG_TRANS("fd=%d, len=%d", fd, len);
return lwip_send(fd, buf, len, flags);
#if defined(STACK_LWIP)
err = lwip_send(fd, buf, len, flags);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
ssize_t zts_sendmsg(int fd, const struct msghdr *msg, int flags)
{
int err = -1;
DEBUG_TRANS("fd=%d", fd);
return lwip_sendmsg(fd, msg, flags);
#if defined(STACK_LWIP)
err = lwip_sendmsg(fd, msg, flags);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
ssize_t zts_recv(int fd, void *buf, size_t len, int flags)
{
int err = -1;
DEBUG_TRANS("fd=%d", fd);
return lwip_recv(fd, buf, len, flags);
#if defined(STACK_LWIP)
err = lwip_recv(fd, buf, len, flags);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
ssize_t zts_recvfrom(int fd, void *buf, size_t len, int flags, struct sockaddr *addr, socklen_t *addrlen)
ssize_t zts_recvfrom(int fd, void *buf, size_t len, int flags,
struct sockaddr *addr, socklen_t *addrlen)
{
int err = -1;
DEBUG_TRANS("fd=%d", fd);
return lwip_recvfrom(fd, buf, len, flags, addr, addrlen);
#if defined(STACK_LWIP)
err = lwip_recvfrom(fd, buf, len, flags, addr, addrlen);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
ssize_t zts_recvmsg(int fd, struct msghdr *msg,int flags)
{
DEBUG_TRANS("fd=%d", fd);
return -1;
int err = -1;
#if defined(STACK_LWIP)
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
int zts_read(int fd, void *buf, size_t len) {
int zts_read(int fd, void *buf, size_t len)
{
int err = -1;
//DEBUG_TRANS("fd=%d, len=%d", fd, len);
return lwip_read(fd, buf, len);
#if defined(STACK_LWIP)
err = lwip_read(fd, buf, len);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
int zts_write(int fd, const void *buf, size_t len) {
int zts_write(int fd, const void *buf, size_t len)
{
//DEBUG_TRANS("fd=%d, len=%d", fd, len);
return lwip_write(fd, buf, len);
int err = -1;
#if defined(STACK_LWIP)
err = lwip_write(fd, buf, len);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
int zts_shutdown(int fd, int how)
{
int err = -1;
DEBUG_EXTRA("fd=%d, how=%d", fd, how);
return lwip_shutdown(fd, how);
#if defined(STACK_LWIP)
err = lwip_shutdown(fd, how);
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
int zts_add_dns_nameserver(struct sockaddr *addr)
{
DEBUG_EXTRA();
return -1;
int err = -1;
#if defined(STACK_LWIP)
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
int zts_del_dns_nameserver(struct sockaddr *addr)
{
DEBUG_EXTRA();
return -1;
int err = -1;
#if defined(STACK_LWIP)
#endif
#if defined(STCK_PICO)
#endif
#if defined(NO_STACK)
#endif
return err;
}
#ifdef __cplusplus

View File

@@ -53,9 +53,12 @@
#include "lwIP.hpp"
netif lwipdev, lwipdev6;
netif lwipdev, lwipdev6, n1;
static bool started = false;
struct netif netifs[10];
bool lwip_driver_initialized = false;
ZeroTier::Mutex driver_m;
err_t tapif_init(struct netif *netif)
{
@@ -78,11 +81,13 @@ static void tcp_timeout(void *data)
// callback for when the TCPIP thread has been successfully started
static void tcpip_init_done(void *arg)
{
DEBUG_EXTRA();
sys_sem_t *sem;
sem = (sys_sem_t *)arg;
netif_set_up(&lwipdev);
DEBUG_INFO("Applications started.");
DEBUG_EXTRA("lwIP stack driver initialized");
lwip_driver_initialized = true;
driver_m.unlock();
DEBUG_EXTRA("released lock");
// sys_timeout(5000, tcp_timeout, NULL);
sys_sem_signal(sem);
}
@@ -90,27 +95,24 @@ static void tcpip_init_done(void *arg)
// main thread which starts the initialization process
static void main_network_stack_thread(void *arg)
{
DEBUG_EXTRA();
sys_sem_t sem;
LWIP_UNUSED_ARG(arg);
if (sys_sem_new(&sem, 0) != ERR_OK) {
DEBUG_ERROR("Failed to create semaphore", 0);
DEBUG_ERROR("failed to create semaphore", 0);
}
tcpip_init(tcpip_init_done, &sem);
sys_sem_wait(&sem);
DEBUG_INFO("TCP/IP initialized.");
DEBUG_EXTRA("tcpip thread started");
sys_sem_wait(&sem);
}
// initialize the lwIP stack
void lwip_driver_init()
{
DEBUG_EXTRA();
// TODO: this should be replaced with something thread-safe
if (started == false) {
started=true;
}
else {
DEBUG_EXTRA("getting lock..");
driver_m.lock(); // unlocked from callback indicating completion of init
DEBUG_EXTRA("got lock");
if (lwip_driver_initialized == true) {
return;
}
sys_thread_new("main_network_stack_thread", main_network_stack_thread,
@@ -158,6 +160,44 @@ err_t lwip_eth_tx(struct netif *netif, struct pbuf *p)
return ERR_OK;
}
void general_lwip_init_interface(void *tapref, struct netif *interface, const char *name, const ZeroTier::MAC &mac, const ZeroTier::InetAddress &addr, const ZeroTier::InetAddress &nm, const ZeroTier::InetAddress &gw)
{
char ipbuf[INET6_ADDRSTRLEN], nmbuf[INET6_ADDRSTRLEN], gwbuf[INET6_ADDRSTRLEN];
static ip_addr_t _addr, _nm, _gw;
IP4_ADDR(&_gw,127,0,0,1);
IP4_ADDR(&_addr,10,6,6,86);
//_addr.addr = *((u32_t *)addr.rawIpData());
_nm.addr = *((u32_t *)addr.netmask().rawIpData());
netif_add(&(n1),&_addr, &_nm, &_gw, NULL, tapif_init, tcpip_input);
n1.state = tapref;
n1.output = etharp_output;
n1.mtu = ZT_MAX_MTU;
n1.name[0] = name[0];
n1.name[1] = name[1];
n1.linkoutput = lwip_eth_tx;
n1.hwaddr_len = 6;
mac.copyTo(n1.hwaddr, n1.hwaddr_len);
n1.flags = NETIF_FLAG_BROADCAST
| NETIF_FLAG_ETHARP
| NETIF_FLAG_IGMP
| NETIF_FLAG_LINK_UP
| NETIF_FLAG_UP;
netif_set_link_up(&n1);
char macbuf[ZT_MAC_ADDRSTRLEN];
mac2str(macbuf, ZT_MAC_ADDRSTRLEN, n1.hwaddr);
DEBUG_INFO("initialized netif as [mac=%s, addr=%s, nm=%s, gw=%s]", macbuf, addr.toString(ipbuf), addr.netmask().toString(nmbuf), gw.toString(gwbuf));
}
void general_turn_on_interface(struct netif *interface)
{
//netif_set_up(&n1);
//netif_set_default(&n1);
//lwipdev.linkoutput = NULL;
//sleep(2);
//netif_set_down(&lwipdev);
//netif_set_link_down(&lwipdev);
}
void lwip_init_interface(void *tapref, const ZeroTier::MAC &mac, const ZeroTier::InetAddress &ip)
{
/* NOTE: It is a known issue that when assigned more than one IP address via
@@ -184,10 +224,10 @@ void lwip_init_interface(void *tapref, const ZeroTier::MAC &mac, const ZeroTier:
| NETIF_FLAG_UP;
netif_set_default(&(lwipdev));
netif_set_link_up(&(lwipdev));
//netif_set_up(&(lwipdev));
netif_set_up(&(lwipdev));
char macbuf[ZT_MAC_ADDRSTRLEN];
mac2str(macbuf, ZT_MAC_ADDRSTRLEN, lwipdev.hwaddr);
DEBUG_INFO("mac=%s, addr=%s, nm=%s", macbuf, ip.toString(ipbuf), ip.netmask().toString(nmbuf));
DEBUG_INFO("initialized netif as [mac=%s, addr=%s, nm=%s]", macbuf, ip.toString(ipbuf), ip.netmask().toString(nmbuf));
}
}
@@ -234,7 +274,24 @@ void lwip_eth_rx(ZeroTier::VirtualTap *tap, const ZeroTier::MAC &from, const Zer
ZeroTier::Utils::ntoh(ethhdr.type), beautify_eth_proto_nums(ZeroTier::Utils::ntoh(ethhdr.type)), flagbuf);
}
{
// Here we select which interface shall receive the Ethernet frames coming in off the ZeroTier virtual wire
// ROUTING CODE SHALL GO HERE
/*
for (int i=0; i<num_netif; i++) {
if (netifs[i].hwaddr == ethhdr.dest.addr) {
// we will use this interface
this->hwaddr;
}
}
*/
#if defined(LIBZT_IPV4)
if (lwipdev.input == NULL)
{
return;
}
if (lwipdev.input(p, &(lwipdev)) != ERR_OK) {
DEBUG_ERROR("error while feeding frame into stack interface (ipv4)");
}