Fix network, ping works again
This commit is contained in:
@@ -25,14 +25,14 @@
|
|||||||
|
|
||||||
static STDCALL void
|
static STDCALL void
|
||||||
vnet_unload_tap() {
|
vnet_unload_tap() {
|
||||||
printf("vnet_unload\n");
|
printf("vnet_unload_tap\n");
|
||||||
COVERAGE_ON();
|
COVERAGE_ON();
|
||||||
COVERAGE_OFF();
|
COVERAGE_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
static STDCALL void
|
static STDCALL void
|
||||||
vnet_reset_tap() {
|
vnet_reset_tap() {
|
||||||
printf("vnet_reset\n");
|
printf("vnet_reset_tap\n");
|
||||||
COVERAGE_ON();
|
COVERAGE_ON();
|
||||||
COVERAGE_OFF();
|
COVERAGE_OFF();
|
||||||
}
|
}
|
||||||
@@ -49,18 +49,18 @@ static STDCALL int
|
|||||||
vnet_transmit_tap(net_buff_t *buf) {
|
vnet_transmit_tap(net_buff_t *buf) {
|
||||||
struct vnet *net;
|
struct vnet *net;
|
||||||
__asm__ __inline__ __volatile__ (
|
__asm__ __inline__ __volatile__ (
|
||||||
"nop"
|
""
|
||||||
: "=b"(net)
|
: "=b"(net)
|
||||||
:
|
:
|
||||||
: "memory");
|
: "memory");
|
||||||
|
|
||||||
printf("vnet_transmit: %d bytes\n", buf->length);
|
printf("vnet_transmit: %d bytes\n", buf->length);
|
||||||
dump_net_buff(buf);
|
dump_net_buff(buf);
|
||||||
write(net->fdout, buf->data, buf->length);
|
ssize_t written = write(net->fdout, buf->data, buf->length);
|
||||||
buf->length = 0;
|
buf->length = 0;
|
||||||
COVERAGE_OFF();
|
COVERAGE_OFF();
|
||||||
COVERAGE_ON();
|
COVERAGE_ON();
|
||||||
printf("vnet_transmit: done\n");
|
printf("vnet_transmit: %d bytes written\n", written);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ vnet_init_tap() {
|
|||||||
int fd, err;
|
int fd, err;
|
||||||
|
|
||||||
if( (fd = open(TAP_DEV, O_RDWR | O_NONBLOCK)) < 0 ) {
|
if( (fd = open(TAP_DEV, O_RDWR | O_NONBLOCK)) < 0 ) {
|
||||||
perror("Opening /dev/net/tun");
|
perror("Opening " TAP_DEV );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,18 +125,23 @@ vnet_init_tap() {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct vnet *net = malloc(sizeof(struct vnet));
|
struct vnet *vnet = malloc(sizeof(struct vnet));
|
||||||
net->netdev.device_type = NET_TYPE_ETH;
|
vnet->eth.net.device_type = NET_TYPE_ETH;
|
||||||
net->netdev.mtu = 1514;
|
vnet->eth.net.mtu = 1514;
|
||||||
net->netdev.name = "UMK0770";
|
char *devname = malloc(8);
|
||||||
|
sprintf(devname, "UMKTAP%d", 0); // FIXME: support more devices
|
||||||
|
vnet->eth.net.name = devname;
|
||||||
|
|
||||||
net->netdev.unload = vnet_unload_tap;
|
vnet->eth.net.unload = vnet_unload_tap;
|
||||||
net->netdev.reset = vnet_reset_tap;
|
vnet->eth.net.reset = vnet_reset_tap;
|
||||||
net->netdev.transmit = vnet_transmit_tap;
|
vnet->eth.net.transmit = vnet_transmit_tap;
|
||||||
|
|
||||||
net->fdin = fd;
|
vnet->fdin = fd;
|
||||||
net->fdout = fd;
|
vnet->fdout = fd;
|
||||||
net->input_processed = 1;
|
vnet->input_processed = 1;
|
||||||
|
|
||||||
return net;
|
memcpy(vnet->eth.mac, (uint8_t[]){0x80, 0x2b, 0xf9, 0x3b, 0x6c, 0xca},
|
||||||
|
sizeof(vnet->eth.mac));
|
||||||
|
|
||||||
|
return vnet;
|
||||||
}
|
}
|
||||||
|
4
shell.c
4
shell.c
@@ -2892,9 +2892,9 @@ cmd_net_add_device(struct shell_ctx *ctx, int argc, char **argv) {
|
|||||||
fputs(usage, ctx->fout);
|
fputs(usage, ctx->fout);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct vnet *net = vnet_init(VNET_TAP); // TODO: list like block devices
|
struct vnet *vnet = vnet_init(VNET_TAP); // TODO: list like block devices
|
||||||
COVERAGE_ON();
|
COVERAGE_ON();
|
||||||
int32_t dev_num = kos_net_add_device(&net->netdev);
|
int32_t dev_num = kos_net_add_device(&vnet->eth.net);
|
||||||
COVERAGE_OFF();
|
COVERAGE_OFF();
|
||||||
fprintf(ctx->fout, "device number: %" PRIi32 "\n", dev_num);
|
fprintf(ctx->fout, "device number: %" PRIi32 "\n", dev_num);
|
||||||
}
|
}
|
||||||
|
55
umka.h
55
umka.h
@@ -22,8 +22,6 @@
|
|||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <signal.h> // for irq0: siginfo_t
|
#include <signal.h> // for irq0: siginfo_t
|
||||||
#else
|
#else
|
||||||
//typedef int32_t ssize_t;
|
|
||||||
//typedef int64_t off_t;
|
|
||||||
typedef void siginfo_t;
|
typedef void siginfo_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -41,6 +39,8 @@ struct umka_ctx {
|
|||||||
#define KEYBOARD_MODE_ASCII 0
|
#define KEYBOARD_MODE_ASCII 0
|
||||||
#define KEYBOARD_MODE_SCANCODES 1
|
#define KEYBOARD_MODE_SCANCODES 1
|
||||||
|
|
||||||
|
#define UMKA_IRQ_BASE 0x20 // skip CPU exceptions
|
||||||
|
#define UMKA_SIGNAL_IRQ SIGSYS
|
||||||
#define UMKA_IRQ_MOUSE 14
|
#define UMKA_IRQ_MOUSE 14
|
||||||
#define UMKA_IRQ_NETWORK 15
|
#define UMKA_IRQ_NETWORK 15
|
||||||
|
|
||||||
@@ -451,41 +451,21 @@ typedef struct {
|
|||||||
// Protocol family
|
// Protocol family
|
||||||
#define AF_INET4 AF_INET
|
#define AF_INET4 AF_INET
|
||||||
|
|
||||||
/*
|
struct net_device;
|
||||||
struct sockaddr_in {
|
|
||||||
uint16_t sin_family; // sa_family_t
|
|
||||||
uint16_t sin_port; // in_port_t
|
|
||||||
uint32_t sin_addr; // struct in_addr
|
|
||||||
uint8_t sin_zero[8]; // zero
|
|
||||||
};
|
|
||||||
|
|
||||||
struct addrinfo {
|
|
||||||
uint32_t ai_flags; // bitmask of AI_*
|
|
||||||
uint32_t ai_family; // PF_*
|
|
||||||
uint32_t ai_socktype; // SOCK_*
|
|
||||||
uint32_t ai_protocol; // 0 or IPPROTO_*
|
|
||||||
uint32_t ai_addrlen; // length of ai_addr
|
|
||||||
uint32_t ai_canonname; // char*
|
|
||||||
uint32_t ai_addr; // struct sockaddr*
|
|
||||||
uint32_t ai_next; // struct addrinfo*
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct net_device_t net_device_t;
|
|
||||||
|
|
||||||
#define NET_BUFFER_SIZE 0x800
|
#define NET_BUFFER_SIZE 0x800
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *next; // pointer to next frame in list
|
void *next; // pointer to next frame in list
|
||||||
void *prev; // pointer to previous frame in list
|
void *prev; // pointer to previous frame in list
|
||||||
net_device_t *device; // ptr to NET_DEVICE structure
|
struct net_device *device; // ptr to NET_DEVICE structure
|
||||||
uint32_t type; // encapsulation type: e.g. Ethernet
|
uint32_t type; // encapsulation type: e.g. Ethernet
|
||||||
size_t length; // size of encapsulated data
|
size_t length; // size of encapsulated data
|
||||||
size_t offset; // offset to actual data (24 bytes for default frame)
|
size_t offset; // offset to actual data (24 bytes for default frame)
|
||||||
uint8_t data[];
|
uint8_t data[];
|
||||||
} net_buff_t;
|
} net_buff_t;
|
||||||
|
|
||||||
struct net_device_t {
|
struct net_device {
|
||||||
uint32_t device_type; // type field
|
uint32_t device_type; // type field
|
||||||
uint32_t mtu; // Maximal Transmission Unit
|
uint32_t mtu; // Maximal Transmission Unit
|
||||||
char *name; // ptr to 0 terminated string
|
char *name; // ptr to 0 terminated string
|
||||||
@@ -495,17 +475,28 @@ struct net_device_t {
|
|||||||
STDCALL void (*reset) (void);
|
STDCALL void (*reset) (void);
|
||||||
STDCALL int (*transmit) (net_buff_t *);
|
STDCALL int (*transmit) (net_buff_t *);
|
||||||
|
|
||||||
uint64_t bytes_tx; // statistics, updated by the driver
|
|
||||||
uint64_t bytes_rx;
|
|
||||||
uint32_t packets_tx;
|
|
||||||
uint32_t packets_rx;
|
|
||||||
|
|
||||||
uint32_t link_state; // link state (0 = no link)
|
uint32_t link_state; // link state (0 = no link)
|
||||||
uint32_t hwacc; // bitmask stating enabled HW accelerations (offload
|
uint32_t hwacc; // bitmask stating enabled HW accelerations (offload
|
||||||
// engines)
|
// engines)
|
||||||
uint8_t mac[6];
|
uint64_t bytes_tx; // statistics, updated by the driver
|
||||||
|
uint64_t bytes_rx;
|
||||||
|
|
||||||
|
uint32_t packets_tx;
|
||||||
|
uint32_t packets_tx_err;
|
||||||
|
uint32_t packets_tx_drop;
|
||||||
|
uint32_t packets_tx_ovr;
|
||||||
|
|
||||||
|
uint32_t packets_rx;
|
||||||
|
uint32_t packets_rx_err;
|
||||||
|
uint32_t packets_rx_drop;
|
||||||
|
uint32_t packets_rx_ovr;
|
||||||
}; // NET_DEVICE
|
}; // NET_DEVICE
|
||||||
|
|
||||||
|
struct eth_device {
|
||||||
|
struct net_device net;
|
||||||
|
uint8_t mac[6];
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t ip;
|
uint32_t ip;
|
||||||
uint8_t mac[6];
|
uint8_t mac[6];
|
||||||
@@ -853,7 +844,7 @@ umka_stack_init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline int32_t
|
static inline int32_t
|
||||||
kos_net_add_device(net_device_t *dev) {
|
kos_net_add_device(struct net_device *dev) {
|
||||||
int32_t dev_num;
|
int32_t dev_num;
|
||||||
__asm__ __inline__ __volatile__ (
|
__asm__ __inline__ __volatile__ (
|
||||||
"call net_add_device"
|
"call net_add_device"
|
||||||
|
88
umka_os.c
88
umka_os.c
@@ -167,21 +167,13 @@ handle_i40(int signo, siginfo_t *info, void *context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_irq_net(int signo, siginfo_t *info, void *context) {
|
hw_int(int signo) {
|
||||||
(void)signo;
|
(void)signo;
|
||||||
(void)info;
|
size_t irq = atomic_load_explicit(&umka_irq_number, memory_order_acquire);
|
||||||
(void)context;
|
struct idt_entry *e = kos_idts + UMKA_IRQ_BASE + irq;
|
||||||
kos_irq_serv_irq10();
|
uintptr_t handler_addr = ((uintptr_t)e->addr_hi << 16) + e->addr_lo;
|
||||||
}
|
void (*irq_handler)(void) = (void(*)(void)) handler_addr;
|
||||||
|
irq_handler();
|
||||||
static void
|
|
||||||
hw_int(int signo, siginfo_t *info, void *context) {
|
|
||||||
(void)signo;
|
|
||||||
(void)context;
|
|
||||||
struct idt_entry *e = kos_idts + info->si_value.sival_int + 0x20;
|
|
||||||
void (*handler)(void) = (void(*)(void)) (((uintptr_t)e->addr_hi << 16)
|
|
||||||
+ e->addr_lo);
|
|
||||||
handler();
|
|
||||||
umka_sti();
|
umka_sti();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,6 +324,14 @@ main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (startupfile) {
|
||||||
|
fstartup = fopen(startupfile, "r");
|
||||||
|
if (!fstartup) {
|
||||||
|
fprintf(stderr, "[!] can't open file for reading: %s\n",
|
||||||
|
startupfile);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (infile) {
|
if (infile) {
|
||||||
fin = fopen(infile, "r");
|
fin = fopen(infile, "r");
|
||||||
if (!fin) {
|
if (!fin) {
|
||||||
@@ -349,49 +349,41 @@ main(int argc, char *argv[]) {
|
|||||||
if (boardlogfile) {
|
if (boardlogfile) {
|
||||||
fboardlog = fopen(boardlogfile, "w");
|
fboardlog = fopen(boardlogfile, "w");
|
||||||
if (!fboardlog) {
|
if (!fboardlog) {
|
||||||
fprintf(stderr, "[!] can't open file for writing: %s\n", outfile);
|
fprintf(stderr, "[!] can't open file for writing: %s\n",
|
||||||
|
boardlogfile);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fboardlog = fout;
|
fboardlog = fout;
|
||||||
}
|
}
|
||||||
|
|
||||||
os = umka_os_init(fin, fout, fboardlog);
|
os = umka_os_init(fstartup, fout, fboardlog);
|
||||||
|
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
sa.sa_sigaction = irq0;
|
sa.sa_sigaction = irq0;
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
sa.sa_flags = SA_SIGINFO;
|
sa.sa_flags = SA_SIGINFO | SA_RESTART;
|
||||||
|
|
||||||
if (sigaction(SIGALRM, &sa, NULL) == -1) {
|
if (sigaction(SIGALRM, &sa, NULL) == -1) {
|
||||||
fprintf(stderr, "Can't install SIGALRM handler!\n");
|
fprintf(stderr, "Can't install timer interrupt handler!\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sa.sa_sigaction = handle_i40;
|
sa.sa_sigaction = handle_i40;
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
sa.sa_flags = SA_SIGINFO;
|
sa.sa_flags = SA_SIGINFO | SA_RESTART;
|
||||||
|
|
||||||
if (sigaction(SIGSEGV, &sa, NULL) == -1) {
|
if (sigaction(SIGSEGV, &sa, NULL) == -1) {
|
||||||
fprintf(stderr, "Can't install SIGSEGV handler!\n");
|
fprintf(stderr, "Can't install 0x40 interrupt handler!\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sa.sa_sigaction = handle_irq_net;
|
sa.sa_handler = hw_int;
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
sa.sa_flags = SA_SIGINFO;
|
sa.sa_flags = SA_RESTART;
|
||||||
|
|
||||||
if (sigaction(SIGUSR1, &sa, NULL) == -1) {
|
if (sigaction(UMKA_SIGNAL_IRQ, &sa, NULL) == -1) {
|
||||||
fprintf(stderr, "Can't install SIGUSR1 handler!\n");
|
fprintf(stderr, "Can't install hardware interrupt handler!\n");
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sa.sa_sigaction = hw_int;
|
|
||||||
sigemptyset(&sa.sa_mask);
|
|
||||||
sa.sa_flags = SA_SIGINFO;
|
|
||||||
|
|
||||||
if (sigaction(SIGSYS, &sa, NULL) == -1) {
|
|
||||||
fprintf(stderr, "Can't install SIGSYS handler!\n");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,16 +400,16 @@ main(int argc, char *argv[]) {
|
|||||||
kos_boot.pitch = UMKA_DEFAULT_DISPLAY_WIDTH * UMKA_DEFAULT_DISPLAY_BPP / 8;
|
kos_boot.pitch = UMKA_DEFAULT_DISPLAY_WIDTH * UMKA_DEFAULT_DISPLAY_BPP / 8;
|
||||||
|
|
||||||
run_test(os->shell);
|
run_test(os->shell);
|
||||||
os->shell->fin = stdin;
|
os->shell->fin = fin;
|
||||||
umka_stack_init();
|
umka_stack_init();
|
||||||
|
|
||||||
// load_app_host("../apps/board_cycle", app);
|
// load_app_host("../apps/board_cycle", app);
|
||||||
load_app_host("../apps/readdir", app);
|
load_app_host("../apps/readdir", app);
|
||||||
// load_app("/rd/1/loader");
|
// load_app("/rd/1/loader");
|
||||||
|
|
||||||
struct vnet *net = vnet_init(VNET_TAP);
|
struct vnet *vnet = vnet_init(VNET_TAP);
|
||||||
if (net) {
|
if (vnet) {
|
||||||
kos_net_add_device(&net->netdev);
|
kos_net_add_device(&vnet->eth.net);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "[!] can't initialize vnet device\n");
|
fprintf(stderr, "[!] can't initialize vnet device\n");
|
||||||
}
|
}
|
||||||
@@ -427,36 +419,34 @@ main(int argc, char *argv[]) {
|
|||||||
umka_sys_net_dev_reset(i);
|
umka_sys_net_dev_reset(i);
|
||||||
umka_sys_net_get_dev_name(i, devname);
|
umka_sys_net_get_dev_name(i, devname);
|
||||||
uint32_t devtype = umka_sys_net_get_dev_type(i);
|
uint32_t devtype = umka_sys_net_get_dev_type(i);
|
||||||
fprintf(stderr, "[net_drv] device %i: %s %u\n", i, devname, devtype);
|
fprintf(stderr, "[!] device %i: %s %u\n", i, devname, devtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// network setup should be done from the userspace app, e.g. via zeroconf
|
// network setup should be done from the userspace app, e.g. via zeroconf
|
||||||
f76ret_t r76;
|
f76ret_t r76;
|
||||||
r76 = umka_sys_net_ipv4_set_subnet(1, inet_addr("255.255.255.0"));
|
r76 = umka_sys_net_ipv4_set_subnet(1, inet_addr("255.255.255.0"));
|
||||||
if (r76.eax == (uint32_t)-1) {
|
if (r76.eax == (uint32_t)-1) {
|
||||||
fprintf(stderr, "[net_drv] set subnet error\n");
|
fprintf(stderr, "[!] set subnet error\n");
|
||||||
return -1;
|
// return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
r76 = umka_sys_net_ipv4_set_gw(1, inet_addr("10.50.0.1"));
|
r76 = umka_sys_net_ipv4_set_gw(1, inet_addr("10.50.0.1"));
|
||||||
if (r76.eax == (uint32_t)-1) {
|
if (r76.eax == (uint32_t)-1) {
|
||||||
fprintf(stderr, "set gw error\n");
|
fprintf(stderr, "[!] set gw error\n");
|
||||||
return -1;
|
// return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
r76 = umka_sys_net_ipv4_set_dns(1, inet_addr("217.10.36.5"));
|
r76 = umka_sys_net_ipv4_set_dns(1, inet_addr("192.168.1.1"));
|
||||||
if (r76.eax == (uint32_t)-1) {
|
if (r76.eax == (uint32_t)-1) {
|
||||||
fprintf(stderr, "[net_drv] set dns error\n");
|
fprintf(stderr, "[!] set dns error\n");
|
||||||
return -1;
|
// return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
r76 = umka_sys_net_ipv4_set_addr(1, inet_addr("10.50.0.2"));
|
r76 = umka_sys_net_ipv4_set_addr(1, inet_addr("10.50.0.2"));
|
||||||
if (r76.eax == (uint32_t)-1) {
|
if (r76.eax == (uint32_t)-1) {
|
||||||
fprintf(stderr, "[net_drv] set ip addr error\n");
|
fprintf(stderr, "[!] set ip addr error\n");
|
||||||
return -1;
|
// return -1;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
kos_attach_int_handler(UMKA_IRQ_MOUSE, hw_int_mouse, NULL);
|
kos_attach_int_handler(UMKA_IRQ_MOUSE, hw_int_mouse, NULL);
|
||||||
|
|
||||||
|
51
vnet.c
51
vnet.c
@@ -14,6 +14,7 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#define _POSIX // to have SIGSYS on windows
|
#define _POSIX // to have SIGSYS on windows
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <stdatomic.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -38,8 +39,8 @@
|
|||||||
static int
|
static int
|
||||||
vnet_input(void *udata) {
|
vnet_input(void *udata) {
|
||||||
umka_sti();
|
umka_sti();
|
||||||
struct vnet *net = udata;
|
struct vnet *vnet = udata;
|
||||||
int fd = net->fdin;
|
int fd = vnet->fdin;
|
||||||
int plen = 0;
|
int plen = 0;
|
||||||
fprintf(stderr, "[vnet] input interrupt\n");
|
fprintf(stderr, "[vnet] input interrupt\n");
|
||||||
net_buff_t *buf = kos_net_buff_alloc(NET_BUFFER_SIZE);
|
net_buff_t *buf = kos_net_buff_alloc(NET_BUFFER_SIZE);
|
||||||
@@ -47,11 +48,12 @@ vnet_input(void *udata) {
|
|||||||
fprintf(stderr, "[vnet] Can't allocate network buffer!\n");
|
fprintf(stderr, "[vnet] Can't allocate network buffer!\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
buf->device = &net->netdev;
|
buf->device = &vnet->eth.net;
|
||||||
plen = read(fd, buf->data, NET_BUFFER_SIZE - offsetof(net_buff_t, data));
|
plen = read(fd, buf->data, NET_BUFFER_SIZE - offsetof(net_buff_t, data));
|
||||||
if (plen == -1) {
|
if (plen == -1) {
|
||||||
plen = 0; // we have just allocated a buffer, so we have to submit it
|
plen = 0; // we have just allocated a buffer, so we have to submit it
|
||||||
}
|
}
|
||||||
|
//if (plen != 0)
|
||||||
fprintf(stderr, "[vnet] read %i bytes\n", plen);
|
fprintf(stderr, "[vnet] read %i bytes\n", plen);
|
||||||
for (int i = 0; i < plen; i++) {
|
for (int i = 0; i < plen; i++) {
|
||||||
fprintf(stderr, " %2.2x", buf->data[i]);
|
fprintf(stderr, " %2.2x", buf->data[i]);
|
||||||
@@ -61,7 +63,7 @@ vnet_input(void *udata) {
|
|||||||
buf->length = plen;
|
buf->length = plen;
|
||||||
buf->offset = offsetof(net_buff_t, data);
|
buf->offset = offsetof(net_buff_t, data);
|
||||||
kos_eth_input(buf);
|
kos_eth_input(buf);
|
||||||
net->input_processed = 1;
|
vnet->input_processed = 1;
|
||||||
|
|
||||||
return 1; // acknowledge our interrupt
|
return 1; // acknowledge our interrupt
|
||||||
}
|
}
|
||||||
@@ -73,8 +75,9 @@ vnet_input_monitor(struct vnet *net) {
|
|||||||
while (1) {
|
while (1) {
|
||||||
if (net->input_processed && poll(&pfd, 1, 0)) {
|
if (net->input_processed && poll(&pfd, 1, 0)) {
|
||||||
net->input_processed = 0;
|
net->input_processed = 0;
|
||||||
umka_irq_number = UMKA_IRQ_NETWORK;
|
atomic_store_explicit(&umka_irq_number, UMKA_IRQ_NETWORK,
|
||||||
raise(SIGSYS);
|
memory_order_release);
|
||||||
|
raise(UMKA_SIGNAL_IRQ);
|
||||||
umka_sti();
|
umka_sti();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,41 +86,47 @@ vnet_input_monitor(struct vnet *net) {
|
|||||||
struct vnet *
|
struct vnet *
|
||||||
vnet_init(enum vnet_type type) {
|
vnet_init(enum vnet_type type) {
|
||||||
// printf("vnet_init\n");
|
// printf("vnet_init\n");
|
||||||
struct vnet *net;
|
struct vnet *vnet;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case VNET_FILE:
|
case VNET_FILE:
|
||||||
net = vnet_init_file();
|
vnet = vnet_init_file();
|
||||||
break;
|
break;
|
||||||
case VNET_TAP:
|
case VNET_TAP:
|
||||||
net = vnet_init_tap();
|
vnet = vnet_init_tap();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "[vnet] bad vnet type: %d\n", type);
|
fprintf(stderr, "[vnet] bad vnet type: %d\n", type);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!net) {
|
if (!vnet) {
|
||||||
fprintf(stderr, "[vnet] device initialization failed\n");
|
fprintf(stderr, "[vnet] device initialization failed\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
net->netdev.bytes_tx = 0;
|
vnet->eth.net.link_state = ETH_LINK_FD + ETH_LINK_10M;
|
||||||
net->netdev.bytes_rx = 0;
|
vnet->eth.net.hwacc = 0;
|
||||||
net->netdev.packets_tx = 0;
|
|
||||||
net->netdev.packets_rx = 0;
|
|
||||||
|
|
||||||
net->netdev.link_state = ETH_LINK_FD + ETH_LINK_10M;
|
vnet->eth.net.bytes_tx = 0;
|
||||||
net->netdev.hwacc = 0;
|
vnet->eth.net.bytes_rx = 0;
|
||||||
memcpy(net->netdev.mac, &(uint8_t[6]){0x80, 0x2b, 0xf9, 0x3b, 0x6c, 0xca},
|
|
||||||
sizeof(net->netdev.mac));
|
|
||||||
|
|
||||||
kos_attach_int_handler(UMKA_IRQ_NETWORK, vnet_input, net);
|
vnet->eth.net.packets_tx = 0;
|
||||||
|
vnet->eth.net.packets_tx_err = 0;
|
||||||
|
vnet->eth.net.packets_tx_drop = 0;
|
||||||
|
vnet->eth.net.packets_tx_ovr = 0;
|
||||||
|
|
||||||
|
vnet->eth.net.packets_rx = 0;
|
||||||
|
vnet->eth.net.packets_rx_err = 0;
|
||||||
|
vnet->eth.net.packets_rx_drop = 0;
|
||||||
|
vnet->eth.net.packets_rx_ovr = 0;
|
||||||
|
|
||||||
|
kos_attach_int_handler(UMKA_IRQ_NETWORK, vnet_input, vnet);
|
||||||
fprintf(stderr, "[vnet] start input_monitor thread\n");
|
fprintf(stderr, "[vnet] start input_monitor thread\n");
|
||||||
uint8_t *stack = malloc(STACK_SIZE);
|
uint8_t *stack = malloc(STACK_SIZE);
|
||||||
size_t tid = umka_new_sys_threads(0, vnet_input_monitor, stack + STACK_SIZE);
|
size_t tid = umka_new_sys_threads(0, vnet_input_monitor, stack + STACK_SIZE);
|
||||||
appdata_t *t = kos_slot_base + tid;
|
appdata_t *t = kos_slot_base + tid;
|
||||||
*(void**)((uint8_t*)t->saved_esp0-12) = net; // param for monitor thread
|
*(void**)((uint8_t*)t->saved_esp0-12) = vnet; // param for monitor thread
|
||||||
// -12 here because in UMKa, unlike real hardware, we don't switch between
|
// -12 here because in UMKa, unlike real hardware, we don't switch between
|
||||||
// kernel and userspace, i.e. stack structure is different
|
// kernel and userspace, i.e. stack structure is different
|
||||||
|
|
||||||
return net;
|
return vnet;
|
||||||
}
|
}
|
||||||
|
2
vnet.h
2
vnet.h
@@ -22,7 +22,7 @@ enum vnet_type {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct vnet {
|
struct vnet {
|
||||||
net_device_t netdev;
|
struct eth_device eth;
|
||||||
int fdin;
|
int fdin;
|
||||||
int fdout;
|
int fdout;
|
||||||
int input_processed;
|
int input_processed;
|
||||||
|
81
vnet/file.c
81
vnet/file.c
@@ -7,9 +7,88 @@
|
|||||||
Copyright (C) 2023 Ivan Baravy <dunkaist@gmail.com>
|
Copyright (C) 2023 Ivan Baravy <dunkaist@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "trace.h"
|
||||||
|
#include "umka.h"
|
||||||
|
#include "vnet.h"
|
||||||
|
|
||||||
|
static STDCALL void
|
||||||
|
vnet_unload_file() {
|
||||||
|
printf("vnet_unload_file\n");
|
||||||
|
COVERAGE_ON();
|
||||||
|
COVERAGE_OFF();
|
||||||
|
}
|
||||||
|
|
||||||
|
static STDCALL void
|
||||||
|
vnet_reset_file() {
|
||||||
|
printf("vnet_reset_file\n");
|
||||||
|
COVERAGE_ON();
|
||||||
|
COVERAGE_OFF();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dump_net_buff(net_buff_t *buf) {
|
||||||
|
for (size_t i = 0; i < buf->length; i++) {
|
||||||
|
printf("%2.2x ", buf->data[i]);
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
static STDCALL int
|
||||||
|
vnet_transmit_file(net_buff_t *buf) {
|
||||||
|
struct vnet *net;
|
||||||
|
__asm__ __inline__ __volatile__ (
|
||||||
|
""
|
||||||
|
: "=b"(net)
|
||||||
|
:
|
||||||
|
: "memory");
|
||||||
|
|
||||||
|
printf("vnet_transmit: %d bytes\n", buf->length);
|
||||||
|
dump_net_buff(buf);
|
||||||
|
write(net->fdout, buf->data, buf->length);
|
||||||
|
buf->length = 0;
|
||||||
|
COVERAGE_OFF();
|
||||||
|
COVERAGE_ON();
|
||||||
|
printf("vnet_transmit: done\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct vnet *
|
struct vnet *
|
||||||
vnet_init_file() {
|
vnet_init_file() {
|
||||||
|
int fdin;
|
||||||
|
int fdout;
|
||||||
|
|
||||||
|
if( (fdin = open("/path/to/fdin", O_RDONLY | O_NONBLOCK)) < 0 ) {
|
||||||
|
perror("[vnet_file] can't open input file");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( (fdout = open("/path/to/fdin", O_WRONLY | O_NONBLOCK)) < 0 ) {
|
||||||
|
perror("[vnet_file] can't open output file");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct vnet *vnet = malloc(sizeof(struct vnet));
|
||||||
|
vnet->eth.net.device_type = NET_TYPE_ETH;
|
||||||
|
vnet->eth.net.mtu = 1514;
|
||||||
|
char *devname = malloc(8);
|
||||||
|
sprintf(devname, "UMKFIL%d", 0); // FIXME: support more devices
|
||||||
|
vnet->eth.net.name = devname;
|
||||||
|
|
||||||
|
vnet->eth.net.unload = vnet_unload_file;
|
||||||
|
vnet->eth.net.reset = vnet_reset_file;
|
||||||
|
vnet->eth.net.transmit = vnet_transmit_file;
|
||||||
|
|
||||||
|
vnet->fdin = fdin;
|
||||||
|
vnet->fdout = fdout;
|
||||||
|
vnet->input_processed = 1;
|
||||||
|
|
||||||
|
memcpy(vnet->eth.mac, (uint8_t[]){0x80, 0x2b, 0xf9, 0x3b, 0x6c, 0xca},
|
||||||
|
sizeof(vnet->eth.mac));
|
||||||
|
|
||||||
|
return vnet;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user