1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 20:08:13 +00:00

Kernel: Add a global routing table

Previously the system had no concept of assigning different routes for
different destination addresses as the default gateway IP address was
directly assigned to a network adapter. This default gateway was
statically assigned and any update  would remove the previously existing
route.

This patch is a beginning step towards implementing #180. It implements
a simple global routing table that is referenced during the routing
process. With this implementation it is now possible for a user or
service (i.e. DHCP) to dynamically add routes to the table.

The routing table will select the most specific route when possible. It
will select any direct match between the destination and routing entry
addresses. If the destination address overlaps between multiple entries,
the Kernel will use the longest prefix match, or the longest number of
matching bits between the destination address and the routing address.
In the event that there is no entries found for a specific destination
address, this implementation supports entries for a default route to be
set for any specified interface.

This is a small first step towards enhancing the system's routing
capabilities. Future enhancements would include referencing a
configuration file at boot to load pre-defined static routes.
This commit is contained in:
brapru 2022-03-12 14:16:13 -05:00 committed by Brian Gianforcaro
parent 0718b20df0
commit 8596b1e0c3
4 changed files with 104 additions and 15 deletions

View file

@ -6,12 +6,37 @@
#pragma once
#include <AK/IPv4Address.h>
#include <AK/NonnullRefPtr.h>
#include <Kernel/Locking/MutexProtected.h>
#include <Kernel/Net/NetworkAdapter.h>
#include <Kernel/Thread.h>
namespace Kernel {
struct Route : public RefCounted<Route> {
Route(IPv4Address const& destination, IPv4Address const& gateway, IPv4Address const& netmask, NonnullRefPtr<NetworkAdapter> adapter)
: destination(destination)
, gateway(gateway)
, netmask(netmask)
, adapter(adapter)
{
}
bool operator==(Route const& other)
{
return destination == other.destination && gateway == other.gateway && netmask == other.netmask && adapter.ptr() == other.adapter.ptr();
}
const IPv4Address destination;
const IPv4Address gateway;
const IPv4Address netmask;
NonnullRefPtr<NetworkAdapter> adapter;
IntrusiveListNode<Route, RefPtr<Route>> route_list_node {};
using RouteList = IntrusiveList<&Route::route_list_node>;
};
struct RoutingDecision {
RefPtr<NetworkAdapter> adapter;
MACAddress next_hop;
@ -25,6 +50,7 @@ enum class UpdateTable {
};
void update_arp_table(IPv4Address const&, MACAddress const&, UpdateTable update);
ErrorOr<void> update_routing_table(IPv4Address const& destination, IPv4Address const& gateway, IPv4Address const& netmask, RefPtr<NetworkAdapter> const adapter, UpdateTable update);
enum class AllowUsingGateway {
Yes,
@ -34,5 +60,6 @@ enum class AllowUsingGateway {
RoutingDecision route_to(IPv4Address const& target, IPv4Address const& source, RefPtr<NetworkAdapter> const through = nullptr, AllowUsingGateway = AllowUsingGateway::Yes);
SpinlockProtected<HashMap<IPv4Address, MACAddress>>& arp_table();
SpinlockProtected<Route::RouteList>& routing_table();
}