20#include "NetworkStack.h"
21#include "pedigree/kernel/LockGuard.h"
22#include "pedigree/kernel/Log.h"
23#include "pedigree/kernel/Metrics.h"
24#include "pedigree/kernel/processor/Processor.h"
27#include "modules/Module.h"
42 : interface(registeredInterface), readers() {}
44 struct netif* interface;
48NetworkStack::DeviceLease::DeviceLease() : m_Device(nullptr), m_Interface(nullptr), m_Lease() {}
50NetworkStack::DeviceLease::DeviceLease(
Network* device,
struct netif* interface,
52 : m_Device(device), m_Interface(interface), m_Lease(pedigree_std::move(lease)) {}
54NetworkStack::DeviceLease::DeviceLease(DeviceLease&& other)
55 : m_Device(other.m_Device),
56 m_Interface(other.m_Interface),
57 m_Lease(pedigree_std::move(other.m_Lease)) {
58 other.m_Device =
nullptr;
59 other.m_Interface =
nullptr;
62NetworkStack::DeviceLease::~DeviceLease() {}
66 m_Lease = pedigree_std::move(other.m_Lease);
67 m_Device = other.m_Device;
68 m_Interface = other.m_Interface;
69 other.m_Device =
nullptr;
70 other.m_Interface =
nullptr;
75#if PEDIGREE_HOSTED_NETWORK_REGRESSION
76extern bool runHostedNetworkStackRegressions();
82 size_t totalLength = p->
tot_len;
86 char* output =
new char[totalLength];
92 Metrics::increment(Metrics::NetworkTxFiltered);
100 if (!pDevice->
send(totalLength,
reinterpret_cast<uintptr_t
>(output))) {
101 Metrics::increment(Metrics::NetworkTxSendFailed);
104 Metrics::increment(Metrics::NetworkTxAccepted);
105 Metrics::add(Metrics::NetworkTxBytes, totalLength);
113static void netifStatusUpdate(
struct netif*
netif) {
121static void netifLinkUpdate(
struct netif*
netif) {
140 netif->output = etharp_output;
141 netif->output_ip6 = ethip6_output;
143 netif_set_status_callback(
netif, netifStatusUpdate);
144 netif_set_link_callback(
netif, netifLinkUpdate);
149static void removeInterface(
void* context) {
150 struct netif* iface =
reinterpret_cast<struct
netif*
>(context);
162 const ip4_addr_t* ipaddr;
163 const ip4_addr_t* netmask;
164 const ip4_addr_t* gateway;
166 struct netif* result;
169static void addInterface(
void* context) {
171 add->result =
netif_add(add->iface, add->ipaddr, add->netmask, add->gateway, add->device,
175NetworkStack::NetworkStack()
178#if THREADS || UTILITY_LINUX
185 if (__atomic_load_n(&stack, __ATOMIC_ACQUIRE)) {
186 FATAL(
"NetworkStack created multiple times.");
189 __atomic_store_n(&stack,
this, __ATOMIC_RELEASE);
191 if (!m_MemPool.initialise(4096, 1600) && !m_MemPool.initialise(2048, 1600) &&
192 !m_MemPool.initialise(1024, 1600)) {
193 ERROR(
"Couldn't get a valid buffer pool for networking use");
197NetworkStack::~NetworkStack() {
199#if THREADS || UTILITY_LINUX
204 DeviceRegistration* registration = it.value();
205 registration->readers.close();
206 registrations.
pushBack(registration);
210#if THREADS || UTILITY_LINUX
216 DeviceRegistration* registration = *it;
217 registration->readers.wait();
219 FATAL(
"NetworkStack could not retire a network interface");
221 delete registration->interface;
225 __atomic_store_n(&stack,
static_cast<NetworkStack*
>(
nullptr), __ATOMIC_RELEASE);
233 Metrics::increment(Metrics::NetworkRxNoDevice);
237 receive(nBytes, packet, device, offset);
243 assert(device.device());
244 Network* pCard = device.device();
247 const size_t packetLength = nBytes;
250 Metrics::increment(Metrics::NetworkRxFiltered);
257 struct pbuf* buf = p;
258 while (buf !=
nullptr) {
259 MemoryCopy(buf->
payload,
reinterpret_cast<void*
>(packet), buf->
len);
267 Metrics::increment(Metrics::NetworkRxNoBuffer);
269 "Network Stack: Out of memory pool space, dropping incoming "
275 struct netif* iface = device.interface();
277 Metrics::increment(Metrics::NetworkRxInputFailed);
281 Metrics::increment(Metrics::NetworkRxAccepted);
282 Metrics::add(Metrics::NetworkRxBytes, packetLength);
287#if THREADS || UTILITY_LINUX
293 if (interfaceNumber >= 0xFFU) {
294 FATAL(
"Too many network interfaces!");
298 ByteSet(iface, 0,
sizeof(*iface));
305 ByteSet(&ipaddr, 0,
sizeof(ipaddr));
306 ByteSet(&netmask, 0,
sizeof(netmask));
307 ByteSet(&gateway, 0,
sizeof(gateway));
309 iface->
name[0] =
'e';
310 iface->
name[1] =
'n';
311 iface->
num = interfaceNumber;
319 FATAL(
"NetworkStack could not register a network interface");
331#if THREADS || UTILITY_LINUX
345 lease =
DeviceLease(device, registration->interface, pedigree_std::move(
reader));
351#if THREADS || UTILITY_LINUX
360 lease =
DeviceLease(pDevice, registration->interface, pedigree_std::move(
reader));
366#if THREADS || UTILITY_LINUX
372#if THREADS || UTILITY_LINUX
379 if (*it == pDevice) {
386 registration->readers.
close();
388#if THREADS || UTILITY_LINUX
392 registration->readers.
wait();
396 FATAL(
"NetworkStack could not retire a network interface");
398 delete registration->interface;
405#if PEDIGREE_HOSTED_NETWORK_REGRESSION
406 if (!runHostedNetworkStackRegressions()) {
407 delete g_NetworkStack;
408 g_NetworkStack =
nullptr;
417 delete g_NetworkStack;
421MODULE_INFO(
"network-stack", &entry, &exit,
"vfs",
"lwip");
static NetworkFilter & instance()
size_t m_NextInterfaceNumber
Tree< Network *, DeviceRegistration * > m_Registrations
void deRegisterDevice(Network *pDevice)
Vector< Network * > m_Children
void receive(size_t nBytes, uintptr_t packet, Network *pCard, uint32_t offset)
MUST_USE_RESULT bool acquireDevice(size_t n, DeviceLease &lease)
void registerDevice(Network *pDevice)
virtual void droppedPacket()
Called when a packet is dropped by the system.
virtual const StationInfo & getStationInfo()
virtual bool send(size_t nBytes, uintptr_t buffer)=0
MUST_USE_RESULT bool tryAcquire(Lease &lease)
static bool inDeviceHardIrq()
bool acquire(size_t n=1, size_t timeoutSecs=0, size_t timeoutUsecs=0)
An iterator applicable for many data structures.
A vector / dynamic array.
void pushBack(const T &value)
void clear(bool freeMem=false)
#define NETIF_FLAG_LINK_UP
#define NETIF_FLAG_ETHERNET
#define NETIF_FLAG_ETHARP
#define NETIF_FLAG_BROADCAST
#define netif_is_up(netif)
void netif_remove(struct netif *netif)
struct netif * netif_add(struct netif *netif, void *state, netif_init_fn init, netif_input_fn input)
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
u8_t pbuf_free(struct pbuf *p)
u16_t pbuf_copy_partial(const struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
#define netif_is_link_up(netif)
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
netif_linkoutput_fn linkoutput
err_t tcpip_callback_wait(tcpip_callback_fn function, void *ctx)
err_t tcpip_input(struct pbuf *p, struct netif *inp)