From 1c94b5e8eb9723149a76ef54d38224c995c1a765 Mon Sep 17 00:00:00 2001 From: Liav A Date: Fri, 4 Jun 2021 07:43:16 +0300 Subject: [PATCH] Kernel: Introduce the NetworkingManagement singleton Instead of initializing network adapters in init.cpp, let's move that logic into a separate class to handle this. Also, it seems like a good idea to shift responsiblity on enumeration of network adapters after the boot process, so this singleton will take care of finding the appropriate network adapter when asked to with an IPv4 address or interface name. With this change being merged, we simplify the creation logic of NetworkAdapter derived classes, so we enumerate the PCI bus only once, searching for driver candidates when doing so, and we let each driver to test if it is resposible for the specified PCI device. --- Kernel/CMakeLists.txt | 1 + Kernel/FileSystem/ProcFS.cpp | 3 +- Kernel/Net/E1000NetworkAdapter.cpp | 19 +++-- Kernel/Net/E1000NetworkAdapter.h | 4 +- Kernel/Net/IPv4Socket.cpp | 5 +- Kernel/Net/LoopbackAdapter.cpp | 8 ++- Kernel/Net/LoopbackAdapter.h | 8 ++- Kernel/Net/NE2000NetworkAdapter.cpp | 15 ++-- Kernel/Net/NE2000NetworkAdapter.h | 4 +- Kernel/Net/NetworkAdapter.cpp | 40 +---------- Kernel/Net/NetworkAdapter.h | 12 ---- Kernel/Net/NetworkTask.cpp | 15 ++-- Kernel/Net/NetworkingManagement.cpp | 101 +++++++++++++++++++++++++++ Kernel/Net/NetworkingManagement.h | 46 ++++++++++++ Kernel/Net/RTL8139NetworkAdapter.cpp | 15 ++-- Kernel/Net/RTL8139NetworkAdapter.h | 4 +- Kernel/Net/Routing.cpp | 11 +-- Kernel/Net/Socket.cpp | 3 +- Kernel/Net/TCPSocket.cpp | 3 +- Kernel/init.cpp | 12 +--- 20 files changed, 212 insertions(+), 117 deletions(-) create mode 100644 Kernel/Net/NetworkingManagement.cpp create mode 100644 Kernel/Net/NetworkingManagement.h diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index 023ab811fed..93f0fd58ee7 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -121,6 +121,7 @@ set(KERNEL_SOURCES Net/LoopbackAdapter.cpp Net/NE2000NetworkAdapter.cpp Net/NetworkAdapter.cpp + Net/NetworkingManagement.cpp Net/NetworkTask.cpp Net/RTL8139NetworkAdapter.cpp Net/Routing.cpp diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp index 434ba03257d..10adb724599 100644 --- a/Kernel/FileSystem/ProcFS.cpp +++ b/Kernel/FileSystem/ProcFS.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -477,7 +478,7 @@ static bool procfs$pid_perf_events(InodeIdentifier identifier, KBufferBuilder& b static bool procfs$net_adapters(InodeIdentifier, KBufferBuilder& builder) { JsonArraySerializer array { builder }; - NetworkAdapter::for_each([&array](auto& adapter) { + NetworkingManagement::the().for_each([&array](auto& adapter) { auto obj = array.add_object(); obj.add("name", adapter.name()); obj.add("class_name", adapter.class_name()); diff --git a/Kernel/Net/E1000NetworkAdapter.cpp b/Kernel/Net/E1000NetworkAdapter.cpp index 69cb0fa5884..03d1fce700a 100644 --- a/Kernel/Net/E1000NetworkAdapter.cpp +++ b/Kernel/Net/E1000NetworkAdapter.cpp @@ -156,18 +156,15 @@ UNMAP_AFTER_INIT static bool is_valid_device_id(u16 device_id) } } -UNMAP_AFTER_INIT void E1000NetworkAdapter::detect() +UNMAP_AFTER_INIT RefPtr E1000NetworkAdapter::try_to_initialize(PCI::Address address) { - PCI::enumerate([&](const PCI::Address& address, PCI::ID id) { - if (address.is_null()) - return; - if (id.vendor_id != (u16)PCIVendorID::Intel) - return; - if (!is_valid_device_id(id.device_id)) - return; - u8 irq = PCI::get_interrupt_line(address); - [[maybe_unused]] auto& unused = adopt_ref(*new E1000NetworkAdapter(address, irq)).leak_ref(); - }); + auto id = PCI::get_id(address); + if (id.vendor_id != (u16)PCIVendorID::Intel) + return {}; + if (!is_valid_device_id(id.device_id)) + return {}; + u8 irq = PCI::get_interrupt_line(address); + return adopt_ref_if_nonnull(new E1000NetworkAdapter(address, irq)); } UNMAP_AFTER_INIT E1000NetworkAdapter::E1000NetworkAdapter(PCI::Address address, u8 irq) diff --git a/Kernel/Net/E1000NetworkAdapter.h b/Kernel/Net/E1000NetworkAdapter.h index e7fa10ad70c..6458ae9d45d 100644 --- a/Kernel/Net/E1000NetworkAdapter.h +++ b/Kernel/Net/E1000NetworkAdapter.h @@ -20,9 +20,8 @@ namespace Kernel { class E1000NetworkAdapter final : public NetworkAdapter , public PCI::Device { public: - static void detect(); + static RefPtr try_to_initialize(PCI::Address); - E1000NetworkAdapter(PCI::Address, u8 irq); virtual ~E1000NetworkAdapter() override; virtual void send_raw(ReadonlyBytes) override; @@ -31,6 +30,7 @@ public: virtual const char* purpose() const override { return class_name(); } private: + E1000NetworkAdapter(PCI::Address, u8 irq); virtual void handle_irq(const RegisterState&) override; virtual const char* class_name() const override { return "E1000NetworkAdapter"; } diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index 260c878e22d..c1c1d5bb1da 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -582,7 +583,7 @@ int IPv4Socket::ioctl(FileDescription&, unsigned request, FlatPtr arg) if (copied_ifname.is_null()) return -EFAULT; - auto adapter = NetworkAdapter::lookup_by_name(copied_ifname); + auto adapter = NetworkingManagement::the().lookup_by_name(copied_ifname); if (!adapter) return -ENODEV; @@ -615,7 +616,7 @@ int IPv4Socket::ioctl(FileDescription&, unsigned request, FlatPtr arg) memcpy(namebuf, ifr.ifr_name, IFNAMSIZ); namebuf[sizeof(namebuf) - 1] = '\0'; - auto adapter = NetworkAdapter::lookup_by_name(namebuf); + auto adapter = NetworkingManagement::the().lookup_by_name(namebuf); if (!adapter) return -ENODEV; diff --git a/Kernel/Net/LoopbackAdapter.cpp b/Kernel/Net/LoopbackAdapter.cpp index 2fd4fb7a50d..647c168550c 100644 --- a/Kernel/Net/LoopbackAdapter.cpp +++ b/Kernel/Net/LoopbackAdapter.cpp @@ -9,15 +9,17 @@ namespace Kernel { -static AK::Singleton s_loopback; +static bool s_loopback_initialized = false; -LoopbackAdapter& LoopbackAdapter::the() +NonnullRefPtr LoopbackAdapter::create() { - return *s_loopback; + return adopt_ref(*new LoopbackAdapter()); } LoopbackAdapter::LoopbackAdapter() { + VERIFY(!s_loopback_initialized); + s_loopback_initialized = true; set_loopback_name(); set_mtu(65536); set_mac_address({ 19, 85, 2, 9, 0x55, 0xaa }); diff --git a/Kernel/Net/LoopbackAdapter.h b/Kernel/Net/LoopbackAdapter.h index ab5c3906f12..b7949793db6 100644 --- a/Kernel/Net/LoopbackAdapter.h +++ b/Kernel/Net/LoopbackAdapter.h @@ -12,10 +12,12 @@ namespace Kernel { class LoopbackAdapter final : public NetworkAdapter { AK_MAKE_ETERNAL -public: - LoopbackAdapter(); - static LoopbackAdapter& the(); +private: + LoopbackAdapter(); + +public: + static NonnullRefPtr create(); virtual ~LoopbackAdapter() override; virtual void send_raw(ReadonlyBytes) override; diff --git a/Kernel/Net/NE2000NetworkAdapter.cpp b/Kernel/Net/NE2000NetworkAdapter.cpp index 31b962d961e..9c542579e77 100644 --- a/Kernel/Net/NE2000NetworkAdapter.cpp +++ b/Kernel/Net/NE2000NetworkAdapter.cpp @@ -135,7 +135,7 @@ struct [[gnu::packed]] received_packet_header { u16 length; }; -UNMAP_AFTER_INIT void NE2000NetworkAdapter::detect() +UNMAP_AFTER_INIT RefPtr NE2000NetworkAdapter::try_to_initialize(PCI::Address address) { constexpr auto ne2k_ids = Array { PCI::ID { 0x10EC, 0x8029 }, // RealTek RTL-8029(AS) @@ -152,14 +152,11 @@ UNMAP_AFTER_INIT void NE2000NetworkAdapter::detect() PCI::ID { 0x12c3, 0x5598 }, // Holtek HT80229 PCI::ID { 0x8c4a, 0x1980 }, // Winbond W89C940 (misprogrammed) }; - PCI::enumerate([&](const PCI::Address& address, PCI::ID id) { - if (address.is_null()) - return; - if (!ne2k_ids.span().contains_slow(id)) - return; - u8 irq = PCI::get_interrupt_line(address); - [[maybe_unused]] auto& unused = adopt_ref(*new NE2000NetworkAdapter(address, irq)).leak_ref(); - }); + auto id = PCI::get_id(address); + if (!ne2k_ids.span().contains_slow(id)) + return {}; + u8 irq = PCI::get_interrupt_line(address); + return adopt_ref_if_nonnull(new NE2000NetworkAdapter(address, irq)); } UNMAP_AFTER_INIT NE2000NetworkAdapter::NE2000NetworkAdapter(PCI::Address address, u8 irq) diff --git a/Kernel/Net/NE2000NetworkAdapter.h b/Kernel/Net/NE2000NetworkAdapter.h index e70ea93ba4c..2bab3cc0edd 100644 --- a/Kernel/Net/NE2000NetworkAdapter.h +++ b/Kernel/Net/NE2000NetworkAdapter.h @@ -18,9 +18,8 @@ namespace Kernel { class NE2000NetworkAdapter final : public NetworkAdapter , public PCI::Device { public: - static void detect(); + static RefPtr try_to_initialize(PCI::Address); - NE2000NetworkAdapter(PCI::Address, u8 irq); virtual ~NE2000NetworkAdapter() override; virtual void send_raw(ReadonlyBytes) override; @@ -29,6 +28,7 @@ public: virtual const char* purpose() const override { return class_name(); } private: + NE2000NetworkAdapter(PCI::Address, u8 irq); virtual void handle_irq(const RegisterState&) override; virtual const char* class_name() const override { return "NE2000NetworkAdapter"; } diff --git a/Kernel/Net/NetworkAdapter.cpp b/Kernel/Net/NetworkAdapter.cpp index c61fb5872da..c386b7362cc 100644 --- a/Kernel/Net/NetworkAdapter.cpp +++ b/Kernel/Net/NetworkAdapter.cpp @@ -12,53 +12,19 @@ #include #include #include +#include #include #include #include namespace Kernel { -static AK::Singleton>> s_table; - -Lockable>& NetworkAdapter::all_adapters() -{ - return *s_table; -} - -RefPtr NetworkAdapter::from_ipv4_address(const IPv4Address& address) -{ - Locker locker(all_adapters().lock()); - for (auto* adapter : all_adapters().resource()) { - if (adapter->ipv4_address() == address || adapter->ipv4_broadcast() == address) - return adapter; - } - if (address[0] == 0 && address[1] == 0 && address[2] == 0 && address[3] == 0) - return LoopbackAdapter::the(); - if (address[0] == 127) - return LoopbackAdapter::the(); - return nullptr; -} - -RefPtr NetworkAdapter::lookup_by_name(const StringView& name) -{ - NetworkAdapter* found_adapter = nullptr; - for_each([&](auto& adapter) { - if (adapter.name() == name) - found_adapter = &adapter; - }); - return found_adapter; -} - NetworkAdapter::NetworkAdapter() { - // FIXME: I wanna lock :( - all_adapters().resource().set(this); } NetworkAdapter::~NetworkAdapter() { - // FIXME: I wanna lock :( - all_adapters().resource().remove(this); } void NetworkAdapter::send_packet(ReadonlyBytes packet) @@ -199,14 +165,14 @@ void NetworkAdapter::set_interface_name(const PCI::Address& pci_address) { // Note: This stands for e - "Ethernet", p - "Port" as for PCI bus, "s" for slot as for PCI slot auto name = String::formatted("ep{}s{}", pci_address.bus(), pci_address.device()); - VERIFY(!lookup_by_name(name)); + VERIFY(!NetworkingManagement::the().lookup_by_name(name)); m_name = move(name); } void NetworkAdapter::set_loopback_name() { auto name = String("loop"); - VERIFY(!lookup_by_name(name)); + VERIFY(!NetworkingManagement::the().lookup_by_name(name)); m_name = move(name); } } diff --git a/Kernel/Net/NetworkAdapter.h b/Kernel/Net/NetworkAdapter.h index a454ee7592f..4ddee225e65 100644 --- a/Kernel/Net/NetworkAdapter.h +++ b/Kernel/Net/NetworkAdapter.h @@ -42,16 +42,6 @@ struct PacketWithTimestamp : public RefCounted { class NetworkAdapter : public RefCounted , public Weakable { public: - template - static inline void for_each(Callback callback) - { - Locker locker(all_adapters().lock()); - for (auto& it : all_adapters().resource()) - callback(*it); - } - - static RefPtr from_ipv4_address(const IPv4Address&); - static RefPtr lookup_by_name(const StringView&); virtual ~NetworkAdapter(); virtual const char* class_name() const = 0; @@ -103,8 +93,6 @@ protected: void set_loopback_name(); private: - static Lockable>& all_adapters(); - MACAddress m_mac_address; IPv4Address m_ipv4_address; IPv4Address m_ipv4_netmask; diff --git a/Kernel/Net/NetworkTask.cpp b/Kernel/Net/NetworkTask.cpp index 99c5f7bc2c2..f65d846b4e4 100644 --- a/Kernel/Net/NetworkTask.cpp +++ b/Kernel/Net/NetworkTask.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -55,7 +56,7 @@ void NetworkTask_main(void*) WaitQueue packet_wait_queue; int pending_packets = 0; - NetworkAdapter::for_each([&](auto& adapter) { + NetworkingManagement::the().for_each([&](auto& adapter) { dmesgln("NetworkTask: {} network adapter found: hw={}", adapter.class_name(), adapter.mac_address().to_string()); if (String(adapter.class_name()) == "LoopbackAdapter") { @@ -74,7 +75,7 @@ void NetworkTask_main(void*) if (pending_packets == 0) return 0; size_t packet_size = 0; - NetworkAdapter::for_each([&](auto& adapter) { + NetworkingManagement::the().for_each([&](auto& adapter) { if (packet_size || !adapter.has_queued_packets()) return; packet_size = adapter.dequeue_packet(buffer, buffer_size, packet_timestamp); @@ -155,7 +156,7 @@ void handle_arp(const EthernetFrameHeader& eth, size_t frame_size) if (packet.operation() == ARPOperation::Request) { // Who has this IP address? - if (auto adapter = NetworkAdapter::from_ipv4_address(packet.target_protocol_address())) { + if (auto adapter = NetworkingManagement::the().from_ipv4_address(packet.target_protocol_address())) { // We do! dbgln("handle_arp: Responding to ARP request for my IPv4 address ({})", adapter->ipv4_address()); ARPPacket response; @@ -193,7 +194,7 @@ void handle_ipv4(const EthernetFrameHeader& eth, size_t frame_size, const Time& dbgln_if(IPV4_DEBUG, "handle_ipv4: source={}, destination={}", packet.source(), packet.destination()); - NetworkAdapter::for_each([&](auto& adapter) { + NetworkingManagement::the().for_each([&](auto& adapter) { if (adapter.link_up()) { auto my_net = adapter.ipv4_address().to_u32() & adapter.ipv4_netmask().to_u32(); auto their_net = packet.source().to_u32() & adapter.ipv4_netmask().to_u32(); @@ -234,7 +235,7 @@ void handle_icmp(const EthernetFrameHeader& eth, const IPv4Packet& ipv4_packet, socket.did_receive(ipv4_packet.source(), 0, { &ipv4_packet, sizeof(IPv4Packet) + ipv4_packet.payload_size() }, packet_timestamp); } - auto adapter = NetworkAdapter::from_ipv4_address(ipv4_packet.destination()); + auto adapter = NetworkingManagement::the().from_ipv4_address(ipv4_packet.destination()); if (!adapter) return; @@ -292,7 +293,7 @@ void handle_udp(const IPv4Packet& ipv4_packet, const Time& packet_timestamp) auto& destination = ipv4_packet.destination(); - if (destination == IPv4Address(255, 255, 255, 255) || NetworkAdapter::from_ipv4_address(destination) || socket->multicast_memberships().contains_slow(destination)) + if (destination == IPv4Address(255, 255, 255, 255) || NetworkingManagement::the().from_ipv4_address(destination) || socket->multicast_memberships().contains_slow(destination)) socket->did_receive(ipv4_packet.source(), udp_packet.source_port(), { &ipv4_packet, sizeof(IPv4Packet) + ipv4_packet.payload_size() }, packet_timestamp); } @@ -365,7 +366,7 @@ void handle_tcp(const IPv4Packet& ipv4_packet, const Time& packet_timestamp) tcp_packet.window_size(), payload_size); - auto adapter = NetworkAdapter::from_ipv4_address(ipv4_packet.destination()); + auto adapter = NetworkingManagement::the().from_ipv4_address(ipv4_packet.destination()); if (!adapter) { dbgln("handle_tcp: this packet is not for me, it's for {}", ipv4_packet.destination()); return; diff --git a/Kernel/Net/NetworkingManagement.cpp b/Kernel/Net/NetworkingManagement.cpp new file mode 100644 index 00000000000..c2bb229b14b --- /dev/null +++ b/Kernel/Net/NetworkingManagement.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2021, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Kernel { + +static AK::Singleton s_the; + +NetworkingManagement& NetworkingManagement::the() +{ + return *s_the; +} + +bool NetworkingManagement::is_initialized() +{ + return s_the.is_initialized(); +} + +UNMAP_AFTER_INIT NetworkingManagement::NetworkingManagement() +{ +} + +NonnullRefPtr NetworkingManagement::loopback_adapter() const +{ + return *m_loopback_adapter; +} + +void NetworkingManagement::for_each(Function callback) +{ + Locker locker(m_lock); + for (auto& it : m_adapters) + callback(it); +} + +RefPtr NetworkingManagement::from_ipv4_address(const IPv4Address& address) const +{ + Locker locker(m_lock); + for (auto& adapter : m_adapters) { + if (adapter.ipv4_address() == address || adapter.ipv4_broadcast() == address) + return adapter; + } + if (address[0] == 0 && address[1] == 0 && address[2] == 0 && address[3] == 0) + return m_loopback_adapter; + if (address[0] == 127) + return m_loopback_adapter; + return {}; +} +RefPtr NetworkingManagement::lookup_by_name(const StringView& name) const +{ + Locker locker(m_lock); + RefPtr found_adapter; + for (auto& it : m_adapters) { + if (it.name() == name) + found_adapter = it; + } + return found_adapter; +} + +UNMAP_AFTER_INIT RefPtr NetworkingManagement::determine_network_device(PCI::Address address) const +{ + if (auto candidate = E1000NetworkAdapter::try_to_initialize(address); !candidate.is_null()) + return candidate; + if (auto candidate = RTL8139NetworkAdapter::try_to_initialize(address); !candidate.is_null()) + return candidate; + if (auto candidate = NE2000NetworkAdapter::try_to_initialize(address); !candidate.is_null()) + return candidate; + return {}; +} + +bool NetworkingManagement::initialize() +{ + PCI::enumerate([&](const PCI::Address& address, PCI::ID) { + // Note: PCI class 2 is the class of Network devices + if (PCI::get_class(address) != 0x02) + return; + if (auto adapter = determine_network_device(address); !adapter.is_null()) + m_adapters.append(adapter.release_nonnull()); + }); + auto loopback = LoopbackAdapter::create(); + m_adapters.append(loopback); + m_loopback_adapter = loopback; + return true; +} + +} diff --git a/Kernel/Net/NetworkingManagement.h b/Kernel/Net/NetworkingManagement.h new file mode 100644 index 00000000000..f8be65a6c8f --- /dev/null +++ b/Kernel/Net/NetworkingManagement.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace Kernel { + +class NetworkAdapter; +class NetworkingManagement { + friend class NetworkAdapter; + AK_MAKE_ETERNAL + +public: + static NetworkingManagement& the(); + static bool is_initialized(); + bool initialize(); + + NetworkingManagement(); + + void for_each(Function); + + RefPtr from_ipv4_address(const IPv4Address&) const; + RefPtr lookup_by_name(const StringView&) const; + + NonnullRefPtr loopback_adapter() const; + +private: + RefPtr determine_network_device(PCI::Address address) const; + + NonnullRefPtrVector m_adapters; + RefPtr m_loopback_adapter; + mutable Lock m_lock { "Networking" }; +}; + +} diff --git a/Kernel/Net/RTL8139NetworkAdapter.cpp b/Kernel/Net/RTL8139NetworkAdapter.cpp index 4ff94318569..e78bd931808 100644 --- a/Kernel/Net/RTL8139NetworkAdapter.cpp +++ b/Kernel/Net/RTL8139NetworkAdapter.cpp @@ -105,17 +105,14 @@ namespace Kernel { #define RX_BUFFER_SIZE 32768 #define TX_BUFFER_SIZE PACKET_SIZE_MAX -UNMAP_AFTER_INIT void RTL8139NetworkAdapter::detect() +UNMAP_AFTER_INIT RefPtr RTL8139NetworkAdapter::try_to_initialize(PCI::Address address) { constexpr PCI::ID rtl8139_id = { 0x10EC, 0x8139 }; - PCI::enumerate([&](const PCI::Address& address, PCI::ID id) { - if (address.is_null()) - return; - if (id != rtl8139_id) - return; - u8 irq = PCI::get_interrupt_line(address); - [[maybe_unused]] auto& unused = adopt_ref(*new RTL8139NetworkAdapter(address, irq)).leak_ref(); - }); + auto id = PCI::get_id(address); + if (id != rtl8139_id) + return {}; + u8 irq = PCI::get_interrupt_line(address); + return adopt_ref_if_nonnull(new RTL8139NetworkAdapter(address, irq)); } UNMAP_AFTER_INIT RTL8139NetworkAdapter::RTL8139NetworkAdapter(PCI::Address address, u8 irq) diff --git a/Kernel/Net/RTL8139NetworkAdapter.h b/Kernel/Net/RTL8139NetworkAdapter.h index 9d1ebe2f1a1..b04ec65d1f6 100644 --- a/Kernel/Net/RTL8139NetworkAdapter.h +++ b/Kernel/Net/RTL8139NetworkAdapter.h @@ -20,9 +20,8 @@ namespace Kernel { class RTL8139NetworkAdapter final : public NetworkAdapter , public PCI::Device { public: - static void detect(); + static RefPtr try_to_initialize(PCI::Address); - RTL8139NetworkAdapter(PCI::Address, u8 irq); virtual ~RTL8139NetworkAdapter() override; virtual void send_raw(ReadonlyBytes) override; @@ -31,6 +30,7 @@ public: virtual const char* purpose() const override { return class_name(); } private: + RTL8139NetworkAdapter(PCI::Address, u8 irq); virtual void handle_irq(const RegisterState&) override; virtual const char* class_name() const override { return "RTL8139NetworkAdapter"; } diff --git a/Kernel/Net/Routing.cpp b/Kernel/Net/Routing.cpp index 41f7e945877..90d7d268fe8 100644 --- a/Kernel/Net/Routing.cpp +++ b/Kernel/Net/Routing.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -142,9 +143,9 @@ RoutingDecision route_to(const IPv4Address& target, const IPv4Address& source, c }; if (target[0] == 0 && target[1] == 0 && target[2] == 0 && target[3] == 0) - return if_matches(LoopbackAdapter::the(), LoopbackAdapter::the().mac_address()); + return if_matches(*NetworkingManagement::the().loopback_adapter(), NetworkingManagement::the().loopback_adapter()->mac_address()); if (target[0] == 127) - return if_matches(LoopbackAdapter::the(), LoopbackAdapter::the().mac_address()); + return if_matches(*NetworkingManagement::the().loopback_adapter(), NetworkingManagement::the().loopback_adapter()->mac_address()); auto target_addr = target.to_u32(); auto source_addr = source.to_u32(); @@ -152,12 +153,12 @@ RoutingDecision route_to(const IPv4Address& target, const IPv4Address& source, c RefPtr local_adapter = nullptr; RefPtr gateway_adapter = nullptr; - NetworkAdapter::for_each([source_addr, &target_addr, &local_adapter, &gateway_adapter, &matches, &through](auto& adapter) { + NetworkingManagement::the().for_each([source_addr, &target_addr, &local_adapter, &gateway_adapter, &matches, &through](NetworkAdapter& adapter) { auto adapter_addr = adapter.ipv4_address().to_u32(); auto adapter_mask = adapter.ipv4_netmask().to_u32(); if (target_addr == adapter_addr) { - local_adapter = LoopbackAdapter::the(); + local_adapter = NetworkingManagement::the().loopback_adapter(); return; } @@ -213,7 +214,7 @@ RoutingDecision route_to(const IPv4Address& target, const IPv4Address& source, c if (target_addr == 0xffffffff && matches(adapter)) return { adapter, { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } }; - if (adapter == LoopbackAdapter::the()) + if (adapter == NetworkingManagement::the().loopback_adapter()) return { adapter, adapter->mac_address() }; if ((target_addr & IPv4Address { 240, 0, 0, 0 }.to_u32()) == IPv4Address { 224, 0, 0, 0 }.to_u32()) diff --git a/Kernel/Net/Socket.cpp b/Kernel/Net/Socket.cpp index 2ff8c6ce69e..1484ff260f1 100644 --- a/Kernel/Net/Socket.cpp +++ b/Kernel/Net/Socket.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -111,7 +112,7 @@ KResult Socket::setsockopt(int level, int option, Userspace user_va auto ifname = copy_string_from_user(user_string, user_value_size); if (ifname.is_null()) return EFAULT; - auto device = NetworkAdapter::lookup_by_name(ifname); + auto device = NetworkingManagement::the().lookup_by_name(ifname); if (!device) return ENODEV; m_bound_interface = device; diff --git a/Kernel/Net/TCPSocket.cpp b/Kernel/Net/TCPSocket.cpp index bb420643665..0fdb838355a 100644 --- a/Kernel/Net/TCPSocket.cpp +++ b/Kernel/Net/TCPSocket.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -357,7 +358,7 @@ NetworkOrdered TCPSocket::compute_tcp_checksum(const IPv4Address& source, c KResult TCPSocket::protocol_bind() { if (has_specific_local_address() && !m_adapter) { - m_adapter = NetworkAdapter::from_ipv4_address(local_address()); + m_adapter = NetworkingManagement::the().from_ipv4_address(local_address()); if (!m_adapter) return EADDRNOTAVAIL; } diff --git a/Kernel/init.cpp b/Kernel/init.cpp index df56ae26e77..3711ec7ed6c 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -33,11 +33,8 @@ #include #include #include -#include -#include -#include #include -#include +#include #include #include #include @@ -243,12 +240,7 @@ void init_stage2(void*) VirtIO::detect(); - E1000NetworkAdapter::detect(); - NE2000NetworkAdapter::detect(); - RTL8139NetworkAdapter::detect(); - - LoopbackAdapter::the(); - + NetworkingManagement::the().initialize(); Syscall::initialize(); new MemoryDevice;