2017-07-25 23:40:24 -07:00
|
|
|
/*
|
2020-04-13 23:38:06 -07:00
|
|
|
* Copyright (c)2013-2020 ZeroTier, Inc.
|
2017-07-25 23:40:24 -07: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-07-25 23:40:24 -07:00
|
|
|
*
|
2020-04-13 23:38:06 -07:00
|
|
|
* Change Date: 2024-01-01
|
2017-07-25 23:40:24 -07: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-07-25 23:40:24 -07:00
|
|
|
*/
|
2020-04-13 23:38:06 -07:00
|
|
|
/****/
|
2017-07-25 23:40:24 -07:00
|
|
|
|
2017-09-27 02:29:04 -07:00
|
|
|
/**
|
|
|
|
|
* @file
|
|
|
|
|
*
|
2019-01-14 12:01:29 -08:00
|
|
|
* lwIP network stack driver
|
2017-09-27 02:29:04 -07:00
|
|
|
*/
|
2017-09-08 16:13:56 -07:00
|
|
|
|
2019-01-25 12:42:53 -08:00
|
|
|
#include <queue>
|
2017-11-06 13:50:20 -08:00
|
|
|
|
2017-09-27 02:29:04 -07:00
|
|
|
#include "MAC.hpp"
|
2019-01-14 12:01:29 -08:00
|
|
|
#include "Mutex.hpp"
|
2017-07-26 02:12:28 -07:00
|
|
|
|
2017-07-25 23:40:24 -07:00
|
|
|
#include "netif/ethernet.h"
|
2017-09-27 02:29:04 -07:00
|
|
|
#include "lwip/netif.h"
|
2017-07-25 23:40:24 -07:00
|
|
|
#include "lwip/etharp.h"
|
2017-09-27 02:29:04 -07:00
|
|
|
#include "lwip/tcpip.h"
|
|
|
|
|
#include "lwip/mem.h"
|
|
|
|
|
#include "lwip/memp.h"
|
|
|
|
|
#include "lwip/sys.h"
|
|
|
|
|
#include "lwip/tcp.h"
|
|
|
|
|
#include "lwip/timeouts.h"
|
|
|
|
|
#include "lwip/stats.h"
|
2017-10-16 12:23:10 -07:00
|
|
|
#include "lwip/ethip6.h"
|
2017-11-06 13:50:20 -08:00
|
|
|
#include "lwip/ip_addr.h"
|
|
|
|
|
#include "lwip/nd6.h"
|
|
|
|
|
#include "lwip/netifapi.h"
|
2020-04-20 23:50:21 -07:00
|
|
|
|
|
|
|
|
#ifdef LWIP_STATS
|
2019-02-27 18:25:29 -08:00
|
|
|
#include "lwip/stats.h"
|
2020-04-20 23:50:21 -07:00
|
|
|
#endif
|
2017-07-25 23:40:24 -07:00
|
|
|
|
2019-02-06 22:00:39 -08:00
|
|
|
#include "VirtualTap.hpp"
|
|
|
|
|
#include "lwipDriver.hpp"
|
2019-03-04 18:04:37 -08:00
|
|
|
#include "ZeroTier.h"
|
2019-02-06 22:00:39 -08:00
|
|
|
#include "Controls.hpp"
|
2019-02-14 17:27:16 -08:00
|
|
|
|
|
|
|
|
extern void postEvent(uint64_t eventCode, void *arg);
|
|
|
|
|
extern void postEvent(uint64_t eventCode);
|
2017-09-08 16:13:56 -07:00
|
|
|
|
2018-02-07 18:03:04 -08:00
|
|
|
#if defined(_WIN32)
|
|
|
|
|
#include <time.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2019-02-06 22:00:39 -08:00
|
|
|
/**
|
|
|
|
|
* Length of human-readable MAC address string
|
|
|
|
|
*/
|
|
|
|
|
#define ZTS_MAC_ADDRSTRLEN 18
|
|
|
|
|
|
2019-02-25 14:52:19 -08:00
|
|
|
#ifndef htonll
|
|
|
|
|
#define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
|
|
|
|
|
#endif
|
|
|
|
|
|
2019-01-31 03:08:48 -08:00
|
|
|
namespace ZeroTier {
|
2018-02-07 11:35:51 -08:00
|
|
|
|
2019-02-07 14:11:17 -08:00
|
|
|
bool _has_exited = false;
|
2019-01-14 12:01:29 -08:00
|
|
|
int hibernationDelayMultiplier = 1;
|
2020-04-13 23:38:06 -07:00
|
|
|
int netifCount = 0;
|
2019-02-06 22:00:39 -08:00
|
|
|
extern bool _run_lwip_tcpip;
|
2019-02-07 14:11:17 -08:00
|
|
|
Mutex lwip_driver_m;
|
2019-02-06 22:00:39 -08:00
|
|
|
|
2019-02-07 14:11:17 -08:00
|
|
|
void lwip_sleep(long ms)
|
|
|
|
|
{
|
|
|
|
|
#if defined(_WIN32)
|
|
|
|
|
Sleep(ms*hibernationDelayMultiplier);
|
|
|
|
|
#else
|
|
|
|
|
usleep(ms*1000*hibernationDelayMultiplier);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
2019-01-26 23:34:04 -08:00
|
|
|
|
2019-01-14 12:01:29 -08:00
|
|
|
void lwip_hibernate_driver()
|
2017-07-25 23:40:24 -07:00
|
|
|
{
|
2019-01-14 12:01:29 -08:00
|
|
|
hibernationDelayMultiplier = ZTS_HIBERNATION_MULTIPLIER;
|
2017-07-25 23:40:24 -07:00
|
|
|
}
|
|
|
|
|
|
2019-01-14 12:01:29 -08:00
|
|
|
void lwip_wake_driver()
|
2017-09-27 02:29:04 -07:00
|
|
|
{
|
2019-01-14 12:01:29 -08:00
|
|
|
hibernationDelayMultiplier = 1;
|
2017-09-27 02:29:04 -07:00
|
|
|
}
|
|
|
|
|
|
2019-01-14 12:01:29 -08:00
|
|
|
// Callback for when the TCPIP thread has been successfully started
|
2017-09-27 02:29:04 -07:00
|
|
|
static void tcpip_init_done(void *arg)
|
|
|
|
|
{
|
|
|
|
|
sys_sem_t *sem;
|
|
|
|
|
sem = (sys_sem_t *)arg;
|
2019-02-06 22:00:39 -08:00
|
|
|
_run_lwip_tcpip = true;
|
2019-02-14 17:27:16 -08:00
|
|
|
postEvent(ZTS_EVENT_STACK_UP);
|
2017-09-27 02:29:04 -07:00
|
|
|
sys_sem_signal(sem);
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-14 12:01:29 -08:00
|
|
|
static void main_lwip_driver_loop(void *arg)
|
2017-09-27 02:29:04 -07:00
|
|
|
{
|
2019-01-25 12:42:53 -08:00
|
|
|
#if defined(__linux__)
|
2019-02-07 14:11:17 -08:00
|
|
|
pthread_setname_np(pthread_self(), ZTS_LWIP_DRIVER_THREAD_NAME);
|
2019-01-25 12:42:53 -08:00
|
|
|
#endif
|
|
|
|
|
#if defined(__APPLE__)
|
2019-02-07 14:11:17 -08:00
|
|
|
pthread_setname_np(ZTS_LWIP_DRIVER_THREAD_NAME);
|
2019-01-25 12:42:53 -08:00
|
|
|
#endif
|
2017-09-27 02:29:04 -07:00
|
|
|
sys_sem_t sem;
|
|
|
|
|
LWIP_UNUSED_ARG(arg);
|
|
|
|
|
if (sys_sem_new(&sem, 0) != ERR_OK) {
|
2018-01-31 17:05:23 -08:00
|
|
|
DEBUG_ERROR("failed to create semaphore");
|
2017-09-27 02:29:04 -07:00
|
|
|
}
|
|
|
|
|
tcpip_init(tcpip_init_done, &sem);
|
|
|
|
|
sys_sem_wait(&sem);
|
2019-02-07 14:11:17 -08:00
|
|
|
// Main loop
|
|
|
|
|
while(_run_lwip_tcpip) {
|
2019-02-27 18:25:29 -08:00
|
|
|
lwip_sleep(LWIP_DRIVER_LOOP_INTERVAL);
|
2018-02-07 11:35:51 -08:00
|
|
|
}
|
2019-02-07 14:11:17 -08:00
|
|
|
_has_exited = true;
|
2019-02-14 17:27:16 -08:00
|
|
|
postEvent(ZTS_EVENT_STACK_DOWN);
|
2019-02-07 14:11:17 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool lwip_is_up()
|
|
|
|
|
{
|
|
|
|
|
Mutex::Lock _l(lwip_driver_m);
|
|
|
|
|
return _run_lwip_tcpip;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool lwip_has_previously_shutdown()
|
|
|
|
|
{
|
|
|
|
|
Mutex::Lock _l(lwip_driver_m);
|
|
|
|
|
return _has_exited;
|
2017-09-27 02:29:04 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void lwip_driver_init()
|
|
|
|
|
{
|
2019-02-07 14:11:17 -08:00
|
|
|
if (lwip_is_up()) {
|
2019-01-14 12:01:29 -08:00
|
|
|
return;
|
2019-02-07 14:11:17 -08:00
|
|
|
}
|
|
|
|
|
if (lwip_has_previously_shutdown()) {
|
2017-09-27 02:29:04 -07:00
|
|
|
return;
|
|
|
|
|
}
|
2019-02-07 14:11:17 -08:00
|
|
|
Mutex::Lock _l(lwip_driver_m);
|
2017-12-19 16:23:52 -08:00
|
|
|
#if defined(_WIN32)
|
2019-01-14 12:01:29 -08:00
|
|
|
sys_init(); // Required for win32 init of critical sections
|
2017-10-09 17:56:40 -07:00
|
|
|
#endif
|
2020-04-20 23:50:21 -07:00
|
|
|
sys_thread_new(ZTS_LWIP_DRIVER_THREAD_NAME, main_lwip_driver_loop,
|
2017-09-27 02:29:04 -07:00
|
|
|
NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-14 12:01:29 -08:00
|
|
|
void lwip_driver_shutdown()
|
|
|
|
|
{
|
2019-02-07 14:11:17 -08:00
|
|
|
if (lwip_has_previously_shutdown()) {
|
2019-01-14 12:01:29 -08:00
|
|
|
return;
|
|
|
|
|
}
|
2019-02-07 14:11:17 -08:00
|
|
|
Mutex::Lock _l(lwip_driver_m);
|
|
|
|
|
// Set flag to stop sending frames into the core
|
|
|
|
|
_run_lwip_tcpip = false;
|
|
|
|
|
// Wait until the main lwIP thread has exited
|
2019-02-27 18:25:29 -08:00
|
|
|
while (!_has_exited) { lwip_sleep(LWIP_DRIVER_LOOP_INTERVAL); }
|
2019-02-06 22:00:39 -08:00
|
|
|
/*
|
2019-01-14 12:01:29 -08:00
|
|
|
if (tcpip_shutdown() == ERR_OK) {
|
|
|
|
|
sys_timeouts_free();
|
|
|
|
|
}
|
2019-02-06 22:00:39 -08:00
|
|
|
*/
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
|
|
|
|
|
2019-02-25 14:52:19 -08:00
|
|
|
void lwip_remove_netif(void *netif)
|
2019-01-14 12:01:29 -08:00
|
|
|
{
|
2020-04-13 23:38:06 -07:00
|
|
|
if (!netif) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-02-25 14:52:19 -08:00
|
|
|
struct netif *n = (struct netif*)netif;
|
|
|
|
|
LOCK_TCPIP_CORE();
|
|
|
|
|
netif_remove(n);
|
|
|
|
|
netif_set_down(n);
|
|
|
|
|
netif_set_link_down(n);
|
|
|
|
|
UNLOCK_TCPIP_CORE();
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
|
|
|
|
|
2019-02-14 17:27:16 -08:00
|
|
|
err_t lwip_eth_tx(struct netif *n, struct pbuf *p)
|
2017-07-25 23:40:24 -07:00
|
|
|
{
|
2020-04-13 23:38:06 -07:00
|
|
|
if (!n) {
|
|
|
|
|
return ERR_IF;
|
|
|
|
|
}
|
2017-08-02 14:54:29 -07:00
|
|
|
struct pbuf *q;
|
|
|
|
|
char buf[ZT_MAX_MTU+32];
|
|
|
|
|
char *bufptr;
|
|
|
|
|
int totalLength = 0;
|
2017-07-25 23:40:24 -07:00
|
|
|
|
2019-02-14 17:27:16 -08:00
|
|
|
VirtualTap *tap = (VirtualTap*)n->state;
|
2017-08-02 14:54:29 -07:00
|
|
|
bufptr = buf;
|
2017-09-18 11:58:41 -07:00
|
|
|
for (q = p; q != NULL; q = q->next) {
|
2017-08-02 14:54:29 -07:00
|
|
|
memcpy(bufptr, q->payload, q->len);
|
|
|
|
|
bufptr += q->len;
|
|
|
|
|
totalLength += q->len;
|
|
|
|
|
}
|
|
|
|
|
struct eth_hdr *ethhdr;
|
|
|
|
|
ethhdr = (struct eth_hdr *)buf;
|
2017-07-25 23:40:24 -07:00
|
|
|
|
2019-02-06 22:00:39 -08:00
|
|
|
MAC src_mac;
|
|
|
|
|
MAC dest_mac;
|
2017-08-02 14:54:29 -07:00
|
|
|
src_mac.setTo(ethhdr->src.addr, 6);
|
|
|
|
|
dest_mac.setTo(ethhdr->dest.addr, 6);
|
2017-07-25 23:40:24 -07:00
|
|
|
|
2017-09-13 22:34:25 -07:00
|
|
|
char *data = buf + sizeof(struct eth_hdr);
|
|
|
|
|
int len = totalLength - sizeof(struct eth_hdr);
|
2019-02-06 22:00:39 -08:00
|
|
|
int proto = Utils::ntoh((uint16_t)ethhdr->type);
|
2017-09-13 22:34:25 -07:00
|
|
|
tap->_handler(tap->_arg, NULL, tap->_nwid, src_mac, dest_mac, proto, 0, data, len);
|
2017-09-15 19:45:49 -07:00
|
|
|
if (ZT_MSG_TRANSFER == true) {
|
2017-09-05 16:51:07 -07:00
|
|
|
char flagbuf[32];
|
|
|
|
|
memset(&flagbuf, 0, 32);
|
2019-02-06 22:00:39 -08:00
|
|
|
char macBuf[ZTS_MAC_ADDRSTRLEN], nodeBuf[16];
|
2019-01-14 12:01:29 -08:00
|
|
|
snprintf(macBuf, ZTS_MAC_ADDRSTRLEN, "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
|
|
|
ethhdr->dest.addr[0], ethhdr->dest.addr[1], ethhdr->dest.addr[2],
|
|
|
|
|
ethhdr->dest.addr[3], ethhdr->dest.addr[4], ethhdr->dest.addr[5]);
|
2019-02-06 22:00:39 -08:00
|
|
|
MAC mac;
|
2017-09-05 16:51:07 -07:00
|
|
|
mac.setTo(ethhdr->dest.addr, 6);
|
|
|
|
|
mac.toAddress(tap->_nwid).toString(nodeBuf);
|
2020-04-13 23:38:06 -07:00
|
|
|
/*
|
|
|
|
|
DEBUG_TRANS("len=%5d dst=%s [%s TX <-- %s] ethertype=0x%04x %s", totalLength, macBuf, nodeBuf, tap->nodeId().c_str(),
|
2019-02-06 22:00:39 -08:00
|
|
|
Utils::ntoh(ethhdr->type), flagbuf);
|
2020-04-13 23:38:06 -07:00
|
|
|
*/
|
2017-09-05 16:51:07 -07:00
|
|
|
}
|
2017-08-02 14:54:29 -07:00
|
|
|
return ERR_OK;
|
2017-07-25 23:40:24 -07:00
|
|
|
}
|
|
|
|
|
|
2019-02-06 22:00:39 -08:00
|
|
|
void lwip_eth_rx(VirtualTap *tap, const MAC &from, const MAC &to, unsigned int etherType,
|
2017-09-27 02:29:04 -07:00
|
|
|
const void *data, unsigned int len)
|
|
|
|
|
{
|
2019-02-27 18:25:29 -08:00
|
|
|
#ifdef LWIP_STATS
|
|
|
|
|
stats_display();
|
|
|
|
|
#endif
|
2019-02-07 14:11:17 -08:00
|
|
|
if (!_run_lwip_tcpip) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-09-27 02:29:04 -07:00
|
|
|
struct pbuf *p,*q;
|
|
|
|
|
struct eth_hdr ethhdr;
|
|
|
|
|
from.copyTo(ethhdr.src.addr, 6);
|
|
|
|
|
to.copyTo(ethhdr.dest.addr, 6);
|
2019-02-06 22:00:39 -08:00
|
|
|
ethhdr.type = Utils::hton((uint16_t)etherType);
|
2020-04-13 23:38:06 -07:00
|
|
|
|
2017-11-13 15:27:56 -08:00
|
|
|
if (ZT_MSG_TRANSFER == true) {
|
|
|
|
|
char flagbuf[32];
|
|
|
|
|
memset(&flagbuf, 0, 32);
|
2019-02-06 22:00:39 -08:00
|
|
|
char macBuf[ZTS_MAC_ADDRSTRLEN], nodeBuf[16];
|
2019-01-14 12:01:29 -08:00
|
|
|
snprintf(macBuf, ZTS_MAC_ADDRSTRLEN, "%02x:%02x:%02x:%02x:%02x:%02x",
|
2019-01-31 03:08:48 -08:00
|
|
|
ethhdr.dest.addr[0], ethhdr.dest.addr[1], ethhdr.dest.addr[2],
|
2019-01-14 12:01:29 -08:00
|
|
|
ethhdr.dest.addr[3], ethhdr.dest.addr[4], ethhdr.dest.addr[5]);
|
2019-02-06 22:00:39 -08:00
|
|
|
MAC mac;
|
2017-11-13 15:27:56 -08:00
|
|
|
mac.setTo(ethhdr.src.addr, 6);
|
|
|
|
|
mac.toAddress(tap->_nwid).toString(nodeBuf);
|
2020-04-13 23:38:06 -07:00
|
|
|
/*
|
|
|
|
|
DEBUG_TRANS("len=%5d dst=%s [%s RX --> %s] ethertype=0x%04x %s", len, macBuf, nodeBuf, tap->nodeId().c_str(),
|
2019-02-06 22:00:39 -08:00
|
|
|
Utils::ntoh(ethhdr.type), flagbuf);
|
2020-04-13 23:38:06 -07:00
|
|
|
*/
|
2017-11-13 15:27:56 -08:00
|
|
|
}
|
2020-04-13 23:38:06 -07:00
|
|
|
|
2020-04-20 23:50:21 -07:00
|
|
|
p = pbuf_alloc(PBUF_RAW, (uint16_t)len+sizeof(struct eth_hdr), PBUF_RAM);
|
2019-01-25 12:42:53 -08:00
|
|
|
if (!p) {
|
|
|
|
|
DEBUG_ERROR("dropped packet: unable to allocate memory for pbuf");
|
2017-09-27 02:29:04 -07:00
|
|
|
return;
|
2017-08-02 14:54:29 -07:00
|
|
|
}
|
2019-01-25 12:42:53 -08:00
|
|
|
// First pbuf gets ethernet header at start
|
|
|
|
|
q = p;
|
|
|
|
|
if (q->len < sizeof(ethhdr)) {
|
2019-01-26 23:34:04 -08:00
|
|
|
pbuf_free(p);
|
|
|
|
|
p = NULL;
|
2019-01-25 12:42:53 -08:00
|
|
|
DEBUG_ERROR("dropped packet: first pbuf smaller than ethernet header");
|
2017-11-13 15:27:56 -08:00
|
|
|
return;
|
2017-08-02 14:54:29 -07:00
|
|
|
}
|
2019-02-20 20:31:02 -08:00
|
|
|
// Copy frame data into pbuf
|
2019-01-25 12:42:53 -08:00
|
|
|
const char *dataptr = reinterpret_cast<const char *>(data);
|
|
|
|
|
memcpy(q->payload,ðhdr,sizeof(ethhdr));
|
|
|
|
|
int remainingPayloadSpace = q->len - sizeof(ethhdr);
|
|
|
|
|
memcpy((char*)q->payload + sizeof(ethhdr),dataptr,remainingPayloadSpace);
|
|
|
|
|
dataptr += remainingPayloadSpace;
|
|
|
|
|
// Remaining pbufs (if any) get rest of data
|
|
|
|
|
while ((q = q->next)) {
|
|
|
|
|
memcpy(q->payload,dataptr,q->len);
|
|
|
|
|
dataptr += q->len;
|
|
|
|
|
}
|
2019-02-20 20:31:02 -08:00
|
|
|
// Feed packet into stack
|
|
|
|
|
int err;
|
2020-04-13 23:38:06 -07:00
|
|
|
|
|
|
|
|
if (Utils::ntoh(ethhdr.type) == 0x800 || Utils::ntoh(ethhdr.type) == 0x806) {
|
|
|
|
|
if ((err = ((struct netif *)tap->netif4)->input(p, (struct netif *)tap->netif4)) != ERR_OK) {
|
|
|
|
|
DEBUG_ERROR("packet input error (%d)", err);
|
|
|
|
|
pbuf_free(p);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (Utils::ntoh(ethhdr.type) == 0x86DD) {
|
|
|
|
|
if ((err = ((struct netif *)tap->netif6)->input(p, (struct netif *)tap->netif6)) != ERR_OK) {
|
|
|
|
|
DEBUG_ERROR("packet input error (%d)", err);
|
|
|
|
|
pbuf_free(p);
|
|
|
|
|
}
|
2017-11-06 13:50:20 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-25 14:52:19 -08:00
|
|
|
/*
|
2019-02-14 17:27:16 -08:00
|
|
|
static void print_netif_info(struct netif *n) {
|
2018-07-25 14:01:12 -07:00
|
|
|
DEBUG_INFO("n=%p, %c%c, %d, o=%p, o6=%p, mc=%x:%x:%x:%x:%x:%x, hwln=%d, st=%p, flgs=%d\n",
|
2019-02-14 17:27:16 -08:00
|
|
|
n,
|
|
|
|
|
n->name[0],
|
|
|
|
|
n->name[1],
|
|
|
|
|
n->mtu,
|
|
|
|
|
n->output,
|
|
|
|
|
n->output_ip6,
|
|
|
|
|
n->hwaddr[0],
|
|
|
|
|
n->hwaddr[1],
|
|
|
|
|
n->hwaddr[2],
|
|
|
|
|
n->hwaddr[3],
|
|
|
|
|
n->hwaddr[4],
|
|
|
|
|
n->hwaddr[5],
|
|
|
|
|
n->hwaddr_len,
|
|
|
|
|
n->state,
|
|
|
|
|
n->flags
|
2018-07-25 14:01:12 -07:00
|
|
|
);
|
|
|
|
|
}
|
2019-02-25 14:52:19 -08:00
|
|
|
*/
|
2018-07-25 14:01:12 -07:00
|
|
|
|
2019-02-14 17:27:16 -08:00
|
|
|
bool lwip_is_netif_up(void *n)
|
2019-01-31 03:08:48 -08:00
|
|
|
{
|
2020-04-13 23:38:06 -07:00
|
|
|
if (!n) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2019-02-20 20:31:02 -08:00
|
|
|
LOCK_TCPIP_CORE();
|
|
|
|
|
bool result = netif_is_up((struct netif*)n);
|
|
|
|
|
UNLOCK_TCPIP_CORE();
|
|
|
|
|
return result;
|
2019-01-26 23:34:04 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Called when a netif is removed (ZTS_EVENT_NETIF_INTERFACE_REMOVED)
|
|
|
|
|
*/
|
2019-02-27 19:20:01 -08:00
|
|
|
#if LWIP_NETIF_REMOVE_CALLBACK
|
2019-02-14 17:27:16 -08:00
|
|
|
static void netif_remove_callback(struct netif *n)
|
2019-01-26 23:34:04 -08:00
|
|
|
{
|
2019-02-20 20:31:02 -08:00
|
|
|
// Called from core, no need to lock
|
2020-04-13 23:38:06 -07:00
|
|
|
if (!n || !n->state) {
|
2019-01-26 23:34:04 -08:00
|
|
|
return;
|
|
|
|
|
}
|
2019-02-14 17:27:16 -08:00
|
|
|
VirtualTap *tap = (VirtualTap *)n->state;
|
|
|
|
|
uint64_t mac = 0;
|
|
|
|
|
memcpy(&mac, n->hwaddr, n->hwaddr_len);
|
|
|
|
|
struct zts_netif_details *ifd = new zts_netif_details;
|
|
|
|
|
ifd->nwid = tap->_nwid;
|
|
|
|
|
memcpy(&(ifd->mac), n->hwaddr, n->hwaddr_len);
|
2019-02-14 17:58:03 -08:00
|
|
|
ifd->mac = lwip_htonl(ifd->mac) >> 16;
|
2019-02-14 17:27:16 -08:00
|
|
|
postEvent(ZTS_EVENT_NETIF_REMOVED, (void*)ifd);
|
2019-01-26 23:34:04 -08:00
|
|
|
}
|
2019-02-27 19:20:01 -08:00
|
|
|
#endif
|
2019-01-26 23:34:04 -08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Called when a link is brought up or down (ZTS_EVENT_NETIF_LINK_UP, ZTS_EVENT_NETIF_LINK_DOWN)
|
|
|
|
|
*/
|
2019-02-27 19:20:01 -08:00
|
|
|
#if LWIP_NETIF_LINK_CALLBACK
|
2019-02-14 17:27:16 -08:00
|
|
|
static void netif_link_callback(struct netif *n)
|
2019-01-26 23:34:04 -08:00
|
|
|
{
|
2019-02-20 20:31:02 -08:00
|
|
|
// Called from core, no need to lock
|
2020-04-13 23:38:06 -07:00
|
|
|
if (!n || !n->state) {
|
2019-01-26 23:34:04 -08:00
|
|
|
return;
|
|
|
|
|
}
|
2019-02-14 17:27:16 -08:00
|
|
|
VirtualTap *tap = (VirtualTap *)n->state;
|
|
|
|
|
uint64_t mac = 0;
|
|
|
|
|
memcpy(&mac, n->hwaddr, n->hwaddr_len);
|
|
|
|
|
if (n->flags & NETIF_FLAG_LINK_UP) {
|
|
|
|
|
struct zts_netif_details *ifd = new zts_netif_details;
|
|
|
|
|
ifd->nwid = tap->_nwid;
|
|
|
|
|
memcpy(&(ifd->mac), n->hwaddr, n->hwaddr_len);
|
2019-02-14 17:58:03 -08:00
|
|
|
ifd->mac = lwip_htonl(ifd->mac) >> 16;
|
2019-02-14 17:27:16 -08:00
|
|
|
postEvent(ZTS_EVENT_NETIF_LINK_UP, (void*)ifd);
|
2019-01-26 23:34:04 -08:00
|
|
|
}
|
2019-02-14 17:27:16 -08:00
|
|
|
if (n->flags & NETIF_FLAG_LINK_UP) {
|
|
|
|
|
struct zts_netif_details *ifd = new zts_netif_details;
|
|
|
|
|
ifd->nwid = tap->_nwid;
|
|
|
|
|
memcpy(&(ifd->mac), n->hwaddr, n->hwaddr_len);
|
2019-02-14 17:58:03 -08:00
|
|
|
ifd->mac = lwip_htonl(ifd->mac) >> 16;
|
2019-02-14 17:27:16 -08:00
|
|
|
postEvent(ZTS_EVENT_NETIF_LINK_DOWN, (void*)ifd);
|
2019-01-26 23:34:04 -08:00
|
|
|
}
|
|
|
|
|
}
|
2019-02-27 19:20:01 -08:00
|
|
|
#endif
|
2018-07-25 14:01:12 -07:00
|
|
|
|
2019-02-14 17:27:16 -08:00
|
|
|
void lwip_set_callbacks(struct netif *n)
|
2018-07-25 14:01:12 -07:00
|
|
|
{
|
2020-04-13 23:38:06 -07:00
|
|
|
if (!n) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-02-14 17:27:16 -08:00
|
|
|
#if LWIP_NETIF_STATUS_CALLBACK
|
2019-02-20 20:31:02 -08:00
|
|
|
// Not currently used
|
2019-02-14 17:27:16 -08:00
|
|
|
netif_set_status_callback(n, netif_status_callback);
|
|
|
|
|
#endif
|
|
|
|
|
#if LWIP_NETIF_REMOVE_CALLBACK
|
|
|
|
|
netif_set_remove_callback(n, netif_remove_callback);
|
|
|
|
|
#endif
|
|
|
|
|
#if LWIP_NETIF_LINK_CALLBACK
|
|
|
|
|
netif_set_link_callback(n, netif_link_callback);
|
|
|
|
|
#endif
|
2018-07-25 14:01:12 -07:00
|
|
|
}
|
|
|
|
|
|
2019-02-25 14:52:19 -08:00
|
|
|
static struct zts_netif_details *lwip_prepare_netif_status_msg(struct netif *n)
|
2018-07-25 14:01:12 -07:00
|
|
|
{
|
2020-04-13 23:38:06 -07:00
|
|
|
if (!n || !n->state) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2019-02-14 17:27:16 -08:00
|
|
|
VirtualTap *tap = (VirtualTap*)(n->state);
|
|
|
|
|
struct zts_netif_details *ifd = new zts_netif_details;
|
|
|
|
|
ifd->nwid = tap->_nwid;
|
|
|
|
|
ifd->mtu = n->mtu;
|
|
|
|
|
memcpy(&(ifd->mac), n->hwaddr, n->hwaddr_len);
|
2019-02-25 14:52:19 -08:00
|
|
|
ifd->mac = htonll(ifd->mac) >> 16;
|
|
|
|
|
return ifd;
|
2019-02-14 17:27:16 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static err_t netif_init(struct netif *n)
|
|
|
|
|
{
|
2020-04-13 23:38:06 -07:00
|
|
|
if (!n || !n->state) {
|
|
|
|
|
return ERR_IF;
|
|
|
|
|
}
|
2019-02-20 20:31:02 -08:00
|
|
|
// Called from netif code, no need to lock
|
2019-02-14 17:27:16 -08:00
|
|
|
n->hwaddr_len = 6;
|
2020-04-13 23:38:06 -07:00
|
|
|
n->name[0] = '4';
|
|
|
|
|
n->name[1] = 'a'+netifCount;
|
2019-02-14 17:27:16 -08:00
|
|
|
n->linkoutput = lwip_eth_tx;
|
|
|
|
|
n->output = etharp_output;
|
2019-02-27 18:25:29 -08:00
|
|
|
n->mtu = LWIP_MTU < ZT_MAX_MTU ? LWIP_MTU : ZT_MAX_MTU;
|
2019-02-14 17:27:16 -08:00
|
|
|
n->flags = NETIF_FLAG_BROADCAST
|
2018-07-25 14:01:12 -07:00
|
|
|
| NETIF_FLAG_ETHARP
|
|
|
|
|
| NETIF_FLAG_ETHERNET
|
|
|
|
|
| NETIF_FLAG_IGMP
|
2019-02-14 17:27:16 -08:00
|
|
|
| NETIF_FLAG_MLD6
|
|
|
|
|
| NETIF_FLAG_LINK_UP
|
|
|
|
|
| NETIF_FLAG_UP;
|
|
|
|
|
n->hwaddr_len = sizeof(n->hwaddr);
|
|
|
|
|
VirtualTap *tap = (VirtualTap*)(n->state);
|
|
|
|
|
tap->_mac.copyTo(n->hwaddr, n->hwaddr_len);
|
2018-07-25 14:01:12 -07:00
|
|
|
return ERR_OK;
|
|
|
|
|
}
|
2018-07-19 17:19:06 -07:00
|
|
|
|
2020-04-13 23:38:06 -07:00
|
|
|
static err_t netif_init6(struct netif *n)
|
|
|
|
|
{
|
|
|
|
|
if (!n || !n->state) {
|
|
|
|
|
return ERR_IF;
|
|
|
|
|
}
|
|
|
|
|
n->hwaddr_len = sizeof(n->hwaddr);
|
|
|
|
|
VirtualTap *tap = (VirtualTap*)(n->state);
|
|
|
|
|
tap->_mac.copyTo(n->hwaddr, n->hwaddr_len);
|
|
|
|
|
// Called from netif code, no need to lock
|
|
|
|
|
n->hwaddr_len = 6;
|
|
|
|
|
n->name[0] = '6';
|
|
|
|
|
n->name[1] = 'a'+netifCount;
|
|
|
|
|
n->linkoutput = lwip_eth_tx;
|
|
|
|
|
n->output_ip6 = ethip6_output;
|
|
|
|
|
n->mtu = LWIP_MTU < ZT_MAX_MTU ? LWIP_MTU : ZT_MAX_MTU;
|
|
|
|
|
n->flags = NETIF_FLAG_BROADCAST
|
|
|
|
|
| NETIF_FLAG_ETHARP
|
|
|
|
|
| NETIF_FLAG_ETHERNET
|
|
|
|
|
| NETIF_FLAG_IGMP
|
|
|
|
|
| NETIF_FLAG_MLD6
|
|
|
|
|
| NETIF_FLAG_LINK_UP
|
|
|
|
|
| NETIF_FLAG_UP;
|
|
|
|
|
return ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-20 23:50:21 -07:00
|
|
|
void lwip_init_interface(void *tapref, const InetAddress &ip)
|
2017-11-21 15:53:31 -08:00
|
|
|
{
|
2019-01-14 12:01:29 -08:00
|
|
|
char ipbuf[INET6_ADDRSTRLEN];
|
|
|
|
|
char macbuf[ZTS_MAC_ADDRSTRLEN];
|
2019-02-14 17:27:16 -08:00
|
|
|
|
|
|
|
|
VirtualTap *vtap = (VirtualTap*)tapref;
|
|
|
|
|
struct netif *n = NULL;
|
2020-04-13 23:38:06 -07:00
|
|
|
bool isNewNetif = false;
|
2017-11-21 15:53:31 -08:00
|
|
|
|
|
|
|
|
if (ip.isV4()) {
|
2020-04-13 23:38:06 -07:00
|
|
|
if (vtap->netif4) {
|
|
|
|
|
n = (struct netif*)vtap->netif4;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
n = new struct netif;
|
|
|
|
|
isNewNetif = true;
|
|
|
|
|
netifCount++;
|
|
|
|
|
}
|
2019-01-14 12:01:29 -08:00
|
|
|
char nmbuf[INET6_ADDRSTRLEN];
|
2020-04-13 23:38:06 -07:00
|
|
|
static ip4_addr_t ip4, netmask, gw;
|
2017-11-21 15:53:31 -08:00
|
|
|
IP4_ADDR(&gw,127,0,0,1);
|
2020-04-13 23:38:06 -07:00
|
|
|
ip4.addr = *((u32_t *)ip.rawIpData());
|
2017-11-21 15:53:31 -08:00
|
|
|
netmask.addr = *((u32_t *)ip.netmask().rawIpData());
|
2019-02-20 20:31:02 -08:00
|
|
|
LOCK_TCPIP_CORE();
|
2020-04-13 23:38:06 -07:00
|
|
|
netif_add(n, &ip4, &netmask, &gw, (void*)vtap, netif_init, tcpip_input);
|
|
|
|
|
vtap->netif4 = (void*)n;
|
2019-02-25 14:52:19 -08:00
|
|
|
postEvent(ZTS_EVENT_NETIF_UP, (void*)lwip_prepare_netif_status_msg(n));
|
2019-02-20 20:31:02 -08:00
|
|
|
UNLOCK_TCPIP_CORE();
|
2019-01-14 12:01:29 -08:00
|
|
|
snprintf(macbuf, ZTS_MAC_ADDRSTRLEN, "%02x:%02x:%02x:%02x:%02x:%02x",
|
2019-01-31 03:08:48 -08:00
|
|
|
n->hwaddr[0], n->hwaddr[1], n->hwaddr[2],
|
|
|
|
|
n->hwaddr[3], n->hwaddr[4], n->hwaddr[5]);
|
2020-04-13 23:38:06 -07:00
|
|
|
DEBUG_INFO("initialized netif=%p as [mac=%s, addr=%s, nm=%s, tap=%p]",n,
|
|
|
|
|
macbuf, ip.toString(ipbuf), ip.netmask().toString(nmbuf), vtap);
|
2017-11-21 15:53:31 -08:00
|
|
|
}
|
2019-02-14 17:27:16 -08:00
|
|
|
if (ip.isV6()) {
|
2020-04-13 23:38:06 -07:00
|
|
|
if (vtap->netif6) {
|
|
|
|
|
n = (struct netif*)vtap->netif6;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
n = new struct netif;
|
|
|
|
|
isNewNetif = true;
|
|
|
|
|
netifCount++;
|
|
|
|
|
}
|
|
|
|
|
static ip6_addr_t ip6;
|
|
|
|
|
memcpy(&(ip6.addr), ip.rawIpData(), sizeof(ip6.addr));
|
2019-02-20 20:31:02 -08:00
|
|
|
LOCK_TCPIP_CORE();
|
2020-04-13 23:38:06 -07:00
|
|
|
if (isNewNetif) {
|
|
|
|
|
vtap->netif6 = (void*)n;
|
|
|
|
|
netif_add(n, NULL, NULL, NULL, (void*)vtap, netif_init6, ethernet_input);
|
|
|
|
|
n->ip6_autoconfig_enabled = 1;
|
|
|
|
|
vtap->_mac.copyTo(n->hwaddr, n->hwaddr_len);
|
|
|
|
|
netif_create_ip6_linklocal_address(n, 1);
|
|
|
|
|
netif_set_link_up(n);
|
|
|
|
|
netif_set_up(n);
|
|
|
|
|
netif_set_default(n);
|
|
|
|
|
}
|
|
|
|
|
netif_add_ip6_address(n,&ip6,NULL);
|
2019-02-14 17:27:16 -08:00
|
|
|
n->output_ip6 = ethip6_output;
|
2019-02-20 20:31:02 -08:00
|
|
|
UNLOCK_TCPIP_CORE();
|
2020-04-13 23:38:06 -07:00
|
|
|
postEvent(ZTS_EVENT_NETIF_UP, (void*)lwip_prepare_netif_status_msg(n));
|
2019-01-14 12:01:29 -08:00
|
|
|
snprintf(macbuf, ZTS_MAC_ADDRSTRLEN, "%02x:%02x:%02x:%02x:%02x:%02x",
|
2019-01-31 03:08:48 -08:00
|
|
|
n->hwaddr[0], n->hwaddr[1], n->hwaddr[2],
|
|
|
|
|
n->hwaddr[3], n->hwaddr[4], n->hwaddr[5]);
|
2020-04-13 23:38:06 -07:00
|
|
|
DEBUG_INFO("initialized netif=%p as [mac=%s, addr=%s, tap=%p]", n,
|
|
|
|
|
macbuf, ip.toString(ipbuf), vtap);
|
2017-11-21 15:53:31 -08:00
|
|
|
}
|
|
|
|
|
}
|
2019-01-31 03:08:48 -08:00
|
|
|
|
|
|
|
|
} // namespace ZeroTier
|