mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
net: loopback device
This commit is contained in:
@@ -69,6 +69,7 @@ void kernel_entry() {
|
|||||||
ext2_init();
|
ext2_init();
|
||||||
|
|
||||||
netdev_init();
|
netdev_init();
|
||||||
|
loopback_init();
|
||||||
arp_init();
|
arp_init();
|
||||||
ipv4_init();
|
ipv4_init();
|
||||||
udp_init();
|
udp_init();
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ typedef struct netdev_t {
|
|||||||
size_t mtu;
|
size_t mtu;
|
||||||
uint32_t ip;
|
uint32_t ip;
|
||||||
hashtable_t arpcache;
|
hashtable_t arpcache;
|
||||||
|
bool doarp;
|
||||||
int (*allocdesc)(size_t requestedsize, netdesc_t *desc);
|
int (*allocdesc)(size_t requestedsize, netdesc_t *desc);
|
||||||
int (*sendpacket)(struct netdev_t *_internal, netdesc_t desc, mac_t targetmac, int proto);
|
int (*sendpacket)(struct netdev_t *_internal, netdesc_t desc, mac_t targetmac, int proto);
|
||||||
} netdev_t;
|
} netdev_t;
|
||||||
@@ -76,6 +77,8 @@ void arp_init();
|
|||||||
void ipv4_init();
|
void ipv4_init();
|
||||||
void udp_init();
|
void udp_init();
|
||||||
void netdev_init();
|
void netdev_init();
|
||||||
|
void loopback_init();
|
||||||
|
netdev_t *loopback_device();
|
||||||
void udp_process(netdev_t *netdev, void *buffer, uint32_t ip);
|
void udp_process(netdev_t *netdev, void *buffer, uint32_t ip);
|
||||||
void arp_process(netdev_t *netdev, void *buffer);
|
void arp_process(netdev_t *netdev, void *buffer);
|
||||||
int arp_lookup(netdev_t *netdev, uint32_t ip, mac_t *mac);
|
int arp_lookup(netdev_t *netdev, uint32_t ip, mac_t *mac);
|
||||||
|
|||||||
@@ -168,9 +168,11 @@ int ipv4_sendpacket(void *buffer, size_t packetsize, uint32_t ip, int proto, net
|
|||||||
if (entry.netdev == NULL)
|
if (entry.netdev == NULL)
|
||||||
return 0; // if a packet can't be routed to anywhere just pretend it was sent somewhere
|
return 0; // if a packet can't be routed to anywhere just pretend it was sent somewhere
|
||||||
|
|
||||||
int error = arp_lookup(entry.netdev, entry.gateway ? entry.gateway : ip, &mac);
|
if (entry.netdev->doarp) {
|
||||||
if (error)
|
int error = arp_lookup(entry.netdev, entry.gateway ? entry.gateway : ip, &mac);
|
||||||
return error;
|
if (error)
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
netdev = entry.netdev;
|
netdev = entry.netdev;
|
||||||
} else {
|
} else {
|
||||||
@@ -207,4 +209,5 @@ void ipv4_init() {
|
|||||||
MUTEX_INIT(&routingtablelock);
|
MUTEX_INIT(&routingtablelock);
|
||||||
routingtable = alloc(sizeof(routingentry_t));
|
routingtable = alloc(sizeof(routingentry_t));
|
||||||
__assert(routingtable);
|
__assert(routingtable);
|
||||||
|
__assert(ipv4_addroute(loopback_device(), 0x7f000001, 0, 0xff000000, 10000) == 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#include <kernel/virtio.h>
|
||||||
|
#include <logging.h>
|
||||||
|
#include <kernel/pmm.h>
|
||||||
|
#include <kernel/eth.h>
|
||||||
|
#include <kernel/net.h>
|
||||||
|
#include <event.h>
|
||||||
|
#include <hashtable.h>
|
||||||
|
#include <arch/cpu.h>
|
||||||
|
|
||||||
|
static netdev_t loopbacknetdev;
|
||||||
|
|
||||||
|
static void rx_dpc(context_t *context, dpcarg_t arg) {
|
||||||
|
eth_process(&loopbacknetdev, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// requested size doesn't account for ethernet header or the virtio header
|
||||||
|
static int loopback_allocdesc(size_t requestedsize, netdesc_t *desc) {
|
||||||
|
desc->address = alloc(requestedsize + sizeof(ethframe_t));
|
||||||
|
if (desc->address == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
|
desc->size = requestedsize + sizeof(ethframe_t);
|
||||||
|
desc->curroffset = sizeof(ethframe_t);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int loopback_sendpacket(netdev_t *netdev, netdesc_t desc, mac_t targetmac, int proto) {
|
||||||
|
desc.curroffset = 0;
|
||||||
|
ethframe_t ethframe = {
|
||||||
|
.type = cpu_to_be_w(proto)
|
||||||
|
};
|
||||||
|
|
||||||
|
mac_t broadcast = NET_BROADCAST_MAC;
|
||||||
|
|
||||||
|
memcpy(ðframe.source, &netdev->mac, sizeof(mac_t));
|
||||||
|
memcpy(ðframe.destination, &broadcast, sizeof(mac_t));
|
||||||
|
memcpy(desc.address, ðframe, sizeof(ethframe_t));
|
||||||
|
|
||||||
|
dpc_t dpc = {0};
|
||||||
|
dpc_enqueue(&dpc, rx_dpc, desc.address);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
netdev_t *loopback_device() {
|
||||||
|
return &loopbacknetdev;
|
||||||
|
}
|
||||||
|
|
||||||
|
void loopback_init() {
|
||||||
|
loopbacknetdev.mtu = 30000;
|
||||||
|
loopbacknetdev.sendpacket = loopback_sendpacket;
|
||||||
|
loopbacknetdev.allocdesc = loopback_allocdesc;
|
||||||
|
loopbacknetdev.ip = 0x7f000001;
|
||||||
|
loopbacknetdev.doarp = false;
|
||||||
|
__assert(hashtable_init(&loopbacknetdev.arpcache, 30) == 0);
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; ++i)
|
||||||
|
loopbacknetdev.mac.address[i] = 0;
|
||||||
|
|
||||||
|
__assert(netdev_register(&loopbacknetdev, "lo") == 0);
|
||||||
|
}
|
||||||
@@ -179,6 +179,7 @@ int vionet_newdevice(viodevice_t *viodevice) {
|
|||||||
netdev->netdev.mtu = 1500;
|
netdev->netdev.mtu = 1500;
|
||||||
netdev->netdev.sendpacket = vionet_sendpacket;
|
netdev->netdev.sendpacket = vionet_sendpacket;
|
||||||
netdev->netdev.allocdesc = vionet_allocdesc;
|
netdev->netdev.allocdesc = vionet_allocdesc;
|
||||||
|
netdev->netdev.doarp = true;
|
||||||
__assert(hashtable_init(&netdev->netdev.arpcache, 30) == 0);
|
__assert(hashtable_init(&netdev->netdev.arpcache, 30) == 0);
|
||||||
|
|
||||||
// initialize queues
|
// initialize queues
|
||||||
|
|||||||
Reference in New Issue
Block a user