Implement vnet_null device
Such device don't need new threads and files but are valid ethernet devices for the kernel. Convenient for testing.
This commit is contained in:
parent
6a479621e9
commit
e71791c0ab
@ -22,31 +22,20 @@
|
|||||||
#include "vnet.h"
|
#include "vnet.h"
|
||||||
|
|
||||||
#define TAP_DEV "/dev/net/tun"
|
#define TAP_DEV "/dev/net/tun"
|
||||||
|
#define UMKA_TAP_NAME "umka%d"
|
||||||
|
|
||||||
static STDCALL void
|
static STDCALL void
|
||||||
vnet_unload_tap(void) {
|
vnet_unload_tap(void) {
|
||||||
printf("vnet_unload_tap\n");
|
|
||||||
COVERAGE_ON();
|
COVERAGE_ON();
|
||||||
COVERAGE_OFF();
|
COVERAGE_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
static STDCALL void
|
static STDCALL void
|
||||||
vnet_reset_tap(void) {
|
vnet_reset_tap(void) {
|
||||||
printf("vnet_reset_tap\n");
|
|
||||||
COVERAGE_ON();
|
COVERAGE_ON();
|
||||||
COVERAGE_OFF();
|
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
|
static STDCALL int
|
||||||
vnet_transmit_tap(net_buff_t *buf) {
|
vnet_transmit_tap(net_buff_t *buf) {
|
||||||
struct vnet *net;
|
struct vnet *net;
|
||||||
@ -56,20 +45,17 @@ vnet_transmit_tap(net_buff_t *buf) {
|
|||||||
:
|
:
|
||||||
: "memory");
|
: "memory");
|
||||||
|
|
||||||
// printf("vnet_transmit: %d bytes\n", buf->length);
|
|
||||||
// dump_net_buff(buf);
|
|
||||||
ssize_t written = write(net->fdout, buf->data, buf->length);
|
ssize_t written = write(net->fdout, buf->data, buf->length);
|
||||||
(void)written;
|
(void)written;
|
||||||
buf->length = 0;
|
buf->length = 0;
|
||||||
COVERAGE_OFF();
|
COVERAGE_OFF();
|
||||||
COVERAGE_ON();
|
COVERAGE_ON();
|
||||||
// printf("vnet_transmit: %d bytes written\n", written);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct vnet *
|
struct vnet *
|
||||||
vnet_init_tap(void) {
|
vnet_init_tap(void) {
|
||||||
struct ifreq ifr = {.ifr_name = UMKA_VNET_NAME,
|
struct ifreq ifr = {.ifr_name = UMKA_TAP_NAME,
|
||||||
.ifr_flags = IFF_TAP | IFF_NO_PI};
|
.ifr_flags = IFF_TAP | IFF_NO_PI};
|
||||||
int fd, err;
|
int fd, err;
|
||||||
|
|
||||||
|
15
makefile
15
makefile
@ -32,6 +32,10 @@ LDFLAGS=-no-pie
|
|||||||
LDFLAGS_32=$(LDFLAGS) -m32
|
LDFLAGS_32=$(LDFLAGS) -m32
|
||||||
LIBS=-lpthread
|
LIBS=-lpthread
|
||||||
|
|
||||||
|
ifeq ($(HOST),windows)
|
||||||
|
LIBS=$(LIBS) -lws2_32
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(HOST),linux)
|
ifeq ($(HOST),linux)
|
||||||
FASM_INCLUDE=$(KOLIBRIOS)/kernel/trunk;$(KOLIBRIOS)/programs/develop/libraries/libcrash/hash
|
FASM_INCLUDE=$(KOLIBRIOS)/kernel/trunk;$(KOLIBRIOS)/programs/develop/libraries/libcrash/hash
|
||||||
FASM=INCLUDE="$(FASM_INCLUDE)" $(FASM_EXE) $(FASM_FLAGS)
|
FASM=INCLUDE="$(FASM_INCLUDE)" $(FASM_EXE) $(FASM_FLAGS)
|
||||||
@ -59,10 +63,10 @@ test: umka_shell
|
|||||||
|
|
||||||
umka_shell: umka_shell.o umka.o shell.o trace.o trace_lbr.o vdisk.o \
|
umka_shell: umka_shell.o umka.o shell.o trace.o trace_lbr.o vdisk.o \
|
||||||
vdisk/raw.o vdisk/qcow2.o deps/em_inflate/em_inflate.o vnet.o \
|
vdisk/raw.o vdisk/qcow2.o deps/em_inflate/em_inflate.o vnet.o \
|
||||||
$(HOST)/vnet/tap.o vnet/file.o lodepng.o $(HOST)/pci.o \
|
$(HOST)/vnet/tap.o vnet/file.o vnet/null.o lodepng.o $(HOST)/pci.o \
|
||||||
$(HOST)/thread.o umkaio.o umkart.o deps/optparse/optparse.o \
|
$(HOST)/thread.o umkaio.o umkart.o deps/optparse/optparse.o \
|
||||||
deps/isocline/src/isocline.o
|
deps/isocline/src/isocline.o
|
||||||
$(CC) $(LDFLAGS_32) $^ -o $@ -T umka.ld $(LIBS) -lws2_32
|
$(CC) $(LDFLAGS_32) $^ -o $@ -T umka.ld $(LIBS)
|
||||||
|
|
||||||
umka_fuse: umka_fuse.o umka.o trace.o trace_lbr.o vdisk.o vdisk/raw.o \
|
umka_fuse: umka_fuse.o umka.o trace.o trace_lbr.o vdisk.o vdisk/raw.o \
|
||||||
vdisk/qcow2.o deps/em_inflate/em_inflate.o $(HOST)/pci.o \
|
vdisk/qcow2.o deps/em_inflate/em_inflate.o $(HOST)/pci.o \
|
||||||
@ -71,8 +75,8 @@ umka_fuse: umka_fuse.o umka.o trace.o trace_lbr.o vdisk.o vdisk/raw.o \
|
|||||||
|
|
||||||
umka_os: umka_os.o umka.o shell.o lodepng.o vdisk.o vdisk/raw.o vdisk/qcow2.o \
|
umka_os: umka_os.o umka.o shell.o lodepng.o vdisk.o vdisk/raw.o vdisk/qcow2.o \
|
||||||
deps/em_inflate/em_inflate.o vnet.o $(HOST)/vnet/tap.o vnet/file.o \
|
deps/em_inflate/em_inflate.o vnet.o $(HOST)/vnet/tap.o vnet/file.o \
|
||||||
trace.o trace_lbr.o $(HOST)/pci.o $(HOST)/thread.o umkaio.o umkart.o \
|
vnet/null.o trace.o trace_lbr.o $(HOST)/pci.o $(HOST)/thread.o \
|
||||||
deps/isocline/src/isocline.o deps/optparse/optparse.o
|
umkaio.o umkart.o deps/isocline/src/isocline.o deps/optparse/optparse.o
|
||||||
$(CC) $(LDFLAGS_32) `sdl2-config --libs` $^ -o $@ -T umka.ld
|
$(CC) $(LDFLAGS_32) `sdl2-config --libs` $^ -o $@ -T umka.ld
|
||||||
|
|
||||||
umka_gen_devices_dat: umka_gen_devices_dat.o umka.o $(HOST)/pci.o \
|
umka_gen_devices_dat: umka_gen_devices_dat.o umka.o $(HOST)/pci.o \
|
||||||
@ -157,6 +161,9 @@ $(HOST)/vnet/tap.o: $(HOST)/vnet/tap.c vnet/tap.h
|
|||||||
vnet/file.o: vnet/file.c vnet/file.h
|
vnet/file.o: vnet/file.c vnet/file.h
|
||||||
$(CC) $(CFLAGS_32) -c $< -o $@
|
$(CC) $(CFLAGS_32) -c $< -o $@
|
||||||
|
|
||||||
|
vnet/null.o: vnet/null.c vnet/null.h
|
||||||
|
$(CC) $(CFLAGS_32) -c $< -o $@
|
||||||
|
|
||||||
umka_shell.o: umka_shell.c umka.h trace.h
|
umka_shell.o: umka_shell.c umka.h trace.h
|
||||||
$(CC) $(CFLAGS_32) -c $<
|
$(CC) $(CFLAGS_32) -c $<
|
||||||
|
|
||||||
|
31
shell.c
31
shell.c
@ -340,7 +340,7 @@ print_hash(struct shell_ctx *ctx, uint8_t *x, size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *host_load_file(const char *fname) {
|
void *host_load_file(const char *fname) {
|
||||||
FILE *f = fopen(fname, "r");
|
FILE *f = fopen(fname, "rb");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1456,7 +1456,7 @@ cmd_get_keyboard_layout(struct shell_ctx *ctx, int argc, char **argv) {
|
|||||||
#undef COLS
|
#undef COLS
|
||||||
} else if (argc == 5 && !strcmp(argv[3], "-f")) {
|
} else if (argc == 5 && !strcmp(argv[3], "-f")) {
|
||||||
const char *fname = argv[4];
|
const char *fname = argv[4];
|
||||||
FILE *f = fopen(fname, "w");
|
FILE *f = fopen(fname, "wb");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
fprintf(ctx->fout, "can't open file for writing: %s\n", fname);
|
fprintf(ctx->fout, "can't open file for writing: %s\n", fname);
|
||||||
fputs(usage, ctx->fout);
|
fputs(usage, ctx->fout);
|
||||||
@ -2898,12 +2898,27 @@ cmd_net_add_device(struct shell_ctx *ctx, int argc, char **argv) {
|
|||||||
(void)ctx;
|
(void)ctx;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
const char *usage = \
|
const char *usage = \
|
||||||
"usage: net_add_device\n";
|
"usage: net_add_device <devtype>\n"
|
||||||
if (argc != 1) {
|
" devtype null, file or tap\n";
|
||||||
|
if (argc > 2) {
|
||||||
fputs(usage, ctx->fout);
|
fputs(usage, ctx->fout);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct vnet *vnet = vnet_init(VNET_TAP); // TODO: list like block devices
|
int devtype = VNET_DEVTYPE_NULL;
|
||||||
|
const char *devtypestr = argv[1];
|
||||||
|
if (devtypestr) {
|
||||||
|
if (!strcmp(devtypestr, "null")) {
|
||||||
|
devtype = VNET_DEVTYPE_NULL;
|
||||||
|
} else if (!strcmp(devtypestr, "file")) {
|
||||||
|
devtype = VNET_DEVTYPE_FILE;
|
||||||
|
} else if (!strcmp(devtypestr, "tap")) {
|
||||||
|
devtype = VNET_DEVTYPE_TAP;
|
||||||
|
} else {
|
||||||
|
fprintf(ctx->fout, "bad device type: %s\n", devtypestr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
struct vnet *vnet = vnet_init(devtype, ctx->running); // TODO: list like block devices
|
||||||
COVERAGE_ON();
|
COVERAGE_ON();
|
||||||
int32_t dev_num = kos_net_add_device(&vnet->eth.net);
|
int32_t dev_num = kos_net_add_device(&vnet->eth.net);
|
||||||
COVERAGE_OFF();
|
COVERAGE_OFF();
|
||||||
@ -4069,8 +4084,8 @@ run_test(struct shell_ctx *ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct shell_ctx *
|
struct shell_ctx *
|
||||||
shell_init(int reproducible, const char *hist_file, struct umka_ctx *umka,
|
shell_init(const int reproducible, const char *hist_file,
|
||||||
struct umka_io *io, FILE *fin, const atomic_int *running) {
|
const struct umka_ctx *umka, const struct umka_io *io, FILE *fin) {
|
||||||
struct shell_ctx *ctx = malloc(sizeof(struct shell_ctx));
|
struct shell_ctx *ctx = malloc(sizeof(struct shell_ctx));
|
||||||
ctx->umka = umka;
|
ctx->umka = umka;
|
||||||
ctx->io = io;
|
ctx->io = io;
|
||||||
@ -4079,7 +4094,7 @@ shell_init(int reproducible, const char *hist_file, struct umka_ctx *umka,
|
|||||||
ctx->var = NULL;
|
ctx->var = NULL;
|
||||||
ctx->fin = fin;
|
ctx->fin = fin;
|
||||||
ctx->fout = stdout;
|
ctx->fout = stdout;
|
||||||
ctx->running = running;
|
ctx->running = &umka->running;
|
||||||
pthread_cond_init(&ctx->cmd_done, NULL);
|
pthread_cond_init(&ctx->cmd_done, NULL);
|
||||||
pthread_mutex_init(&ctx->cmd_mutex, NULL);
|
pthread_mutex_init(&ctx->cmd_mutex, NULL);
|
||||||
return ctx;
|
return ctx;
|
||||||
|
6
shell.h
6
shell.h
@ -37,7 +37,7 @@ struct shell_var {
|
|||||||
|
|
||||||
struct shell_ctx {
|
struct shell_ctx {
|
||||||
const struct umka_ctx *umka;
|
const struct umka_ctx *umka;
|
||||||
struct umka_io *io;
|
const struct umka_io *io;
|
||||||
int reproducible;
|
int reproducible;
|
||||||
const char *hist_file;
|
const char *hist_file;
|
||||||
struct shell_var *var;
|
struct shell_var *var;
|
||||||
@ -50,8 +50,8 @@ struct shell_ctx {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct shell_ctx *
|
struct shell_ctx *
|
||||||
shell_init(int reproducible, const char *hist_file, struct umka_ctx *umka,
|
shell_init(const int reproducible, const char *hist_file,
|
||||||
struct umka_io *io, FILE *fin, const atomic_int *running);
|
const struct umka_ctx *umka, const struct umka_io *io, FILE *fin);
|
||||||
|
|
||||||
void
|
void
|
||||||
shell_close(struct shell_ctx *shell);
|
shell_close(struct shell_ctx *shell);
|
||||||
|
7
umka.asm
7
umka.asm
@ -114,7 +114,7 @@ pubsym coverage_end
|
|||||||
|
|
||||||
pubsym sha3_256_oneshot, 'hash_oneshot'
|
pubsym sha3_256_oneshot, 'hash_oneshot'
|
||||||
pubsym kos_time_to_epoch
|
pubsym kos_time_to_epoch
|
||||||
pubsym umka_init
|
pubsym umka_init, 4
|
||||||
pubsym umka_close, 4
|
pubsym umka_close, 4
|
||||||
pubsym umka_boot
|
pubsym umka_boot
|
||||||
|
|
||||||
@ -578,11 +578,12 @@ struct umka_ctx
|
|||||||
running dd ?
|
running dd ?
|
||||||
ends
|
ends
|
||||||
|
|
||||||
proc umka_init c uses ebx esi edi ebp
|
proc umka_init c uses ebx esi edi ebp, _running
|
||||||
call umka._.check_alignment
|
call umka._.check_alignment
|
||||||
mov eax, umka
|
mov eax, umka
|
||||||
mov [eax+umka_ctx.booted], 0
|
mov [eax+umka_ctx.booted], 0
|
||||||
mov [eax+umka_ctx.running], 0
|
mov ecx, [_running]
|
||||||
|
mov [eax+umka_ctx.running], ecx
|
||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
|
8
umka.h
8
umka.h
@ -29,6 +29,12 @@ typedef void siginfo_t;
|
|||||||
|
|
||||||
#define STDCALL __attribute__((__stdcall__))
|
#define STDCALL __attribute__((__stdcall__))
|
||||||
|
|
||||||
|
enum {
|
||||||
|
UMKA_RUNNING_NEVER,
|
||||||
|
UMKA_RUNNING_NOT_YET,
|
||||||
|
UMKA_RUNNING_YES,
|
||||||
|
};
|
||||||
|
|
||||||
struct umka_ctx {
|
struct umka_ctx {
|
||||||
int booted;
|
int booted;
|
||||||
atomic_int running;
|
atomic_int running;
|
||||||
@ -542,7 +548,7 @@ void
|
|||||||
irq0(int signo, siginfo_t *info, void *context);
|
irq0(int signo, siginfo_t *info, void *context);
|
||||||
|
|
||||||
struct umka_ctx *
|
struct umka_ctx *
|
||||||
umka_init(void);
|
umka_init(int running);
|
||||||
|
|
||||||
void
|
void
|
||||||
umka_close(struct umka_ctx *ctx);
|
umka_close(struct umka_ctx *ctx);
|
||||||
|
@ -35,7 +35,7 @@ struct umka_fuse_ctx {
|
|||||||
static struct umka_fuse_ctx *
|
static struct umka_fuse_ctx *
|
||||||
umka_fuse_init(void) {
|
umka_fuse_init(void) {
|
||||||
struct umka_fuse_ctx *ctx = malloc(sizeof(struct umka_fuse_ctx));
|
struct umka_fuse_ctx *ctx = malloc(sizeof(struct umka_fuse_ctx));
|
||||||
ctx->umka = umka_init();
|
ctx->umka = umka_init(UMKA_RUNNING_NEVER);
|
||||||
ctx->io = io_init(&ctx->umka->running);
|
ctx->io = io_init(&ctx->umka->running);
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ main (int argc, char *argv[]) {
|
|||||||
|
|
||||||
strcpy(pci_path, PCI_BASE_DIR);
|
strcpy(pci_path, PCI_BASE_DIR);
|
||||||
|
|
||||||
umka_init();
|
umka_init(UMKA_RUNNING_NEVER);
|
||||||
kos_acpi_aml_init();
|
kos_acpi_aml_init();
|
||||||
ctx = kos_acpi_aml_new_thread();
|
ctx = kos_acpi_aml_new_thread();
|
||||||
kos_acpi_dev_size = MAX_PCI_DEVICES*16;
|
kos_acpi_dev_size = MAX_PCI_DEVICES*16;
|
||||||
|
14
umka_os.c
14
umka_os.c
@ -72,14 +72,15 @@ struct umka_os_ctx *
|
|||||||
umka_os_init(FILE *fstartup, FILE *fboardlog) {
|
umka_os_init(FILE *fstartup, FILE *fboardlog) {
|
||||||
struct umka_os_ctx *ctx = malloc(sizeof(struct umka_os_ctx));
|
struct umka_os_ctx *ctx = malloc(sizeof(struct umka_os_ctx));
|
||||||
ctx->fboardlog = fboardlog;
|
ctx->fboardlog = fboardlog;
|
||||||
ctx->umka = umka_init();
|
ctx->umka = umka_init(UMKA_RUNNING_NOT_YET);
|
||||||
ctx->io = io_init(&ctx->umka->running);
|
ctx->io = io_init(&ctx->umka->running);
|
||||||
ctx->shell = shell_init(SHELL_LOG_NONREPRODUCIBLE, history_filename,
|
ctx->shell = shell_init(SHELL_LOG_NONREPRODUCIBLE, history_filename,
|
||||||
ctx->umka, ctx->io, fstartup, &ctx->umka->running);
|
ctx->umka, ctx->io, fstartup);
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void build_history_filename(void) {
|
static void
|
||||||
|
build_history_filename(void) {
|
||||||
const char *dir_name;
|
const char *dir_name;
|
||||||
if (!(dir_name = getenv("HOME"))) {
|
if (!(dir_name = getenv("HOME"))) {
|
||||||
dir_name = ".";
|
dir_name = ".";
|
||||||
@ -87,7 +88,8 @@ void build_history_filename(void) {
|
|||||||
sprintf(history_filename, "%s/%s", dir_name, HIST_FILE_BASENAME);
|
sprintf(history_filename, "%s/%s", dir_name, HIST_FILE_BASENAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
void umka_thread_net_drv(void);
|
void
|
||||||
|
umka_thread_net_drv(void);
|
||||||
|
|
||||||
struct itimerval timeout = {.it_value = {.tv_sec = 0, .tv_usec = 10000},
|
struct itimerval timeout = {.it_value = {.tv_sec = 0, .tv_usec = 10000},
|
||||||
.it_interval = {.tv_sec = 0, .tv_usec = 10000}};
|
.it_interval = {.tv_sec = 0, .tv_usec = 10000}};
|
||||||
@ -401,7 +403,7 @@ main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
// load_app("/rd/1/loader");
|
// load_app("/rd/1/loader");
|
||||||
|
|
||||||
struct vnet *vnet = vnet_init(VNET_TAP);
|
struct vnet *vnet = vnet_init(VNET_DEVTYPE_TAP, &os->umka->running);
|
||||||
if (vnet) {
|
if (vnet) {
|
||||||
kos_net_add_device(&vnet->eth.net);
|
kos_net_add_device(&vnet->eth.net);
|
||||||
} else {
|
} else {
|
||||||
@ -462,7 +464,7 @@ main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
setitimer(ITIMER_REAL, &timeout, NULL);
|
setitimer(ITIMER_REAL, &timeout, NULL);
|
||||||
|
|
||||||
atomic_store_explicit(&os->umka->running, 1, memory_order_release);
|
atomic_store_explicit(&os->umka->running, UMKA_RUNNING_YES, memory_order_release);
|
||||||
umka_osloop(); // doesn't return
|
umka_osloop(); // doesn't return
|
||||||
|
|
||||||
if (coverage)
|
if (coverage)
|
||||||
|
@ -34,10 +34,10 @@ char history_filename[PATH_MAX];
|
|||||||
struct umka_shell_ctx *
|
struct umka_shell_ctx *
|
||||||
umka_shell_init(int reproducible, FILE *fin) {
|
umka_shell_init(int reproducible, FILE *fin) {
|
||||||
struct umka_shell_ctx *ctx = malloc(sizeof(struct umka_shell_ctx));
|
struct umka_shell_ctx *ctx = malloc(sizeof(struct umka_shell_ctx));
|
||||||
ctx->umka = umka_init();
|
ctx->umka = umka_init(UMKA_RUNNING_NEVER);
|
||||||
ctx->io = io_init(NULL);
|
ctx->io = io_init(NULL);
|
||||||
ctx->shell = shell_init(reproducible, history_filename, ctx->umka, ctx->io,
|
ctx->shell = shell_init(reproducible, history_filename, ctx->umka, ctx->io,
|
||||||
fin, &ctx->umka->running);
|
fin);
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
umkaio.c
4
umkaio.c
@ -122,7 +122,7 @@ io_close(struct umka_io *io) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
io_read(int fd, void *buf, size_t count, struct umka_io *io) {
|
io_read(int fd, void *buf, size_t count, const struct umka_io *io) {
|
||||||
ssize_t res;
|
ssize_t res;
|
||||||
if (!io->running || !*io->running) {
|
if (!io->running || !*io->running) {
|
||||||
res = read(fd, buf, count);
|
res = read(fd, buf, count);
|
||||||
@ -133,7 +133,7 @@ io_read(int fd, void *buf, size_t count, struct umka_io *io) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
io_write(int fd, const void *buf, size_t count, struct umka_io *io) {
|
io_write(int fd, const void *buf, size_t count, const struct umka_io *io) {
|
||||||
ssize_t res;
|
ssize_t res;
|
||||||
if (!io->running || !*io->running) {
|
if (!io->running || !*io->running) {
|
||||||
res = write(fd, buf, count);
|
res = write(fd, buf, count);
|
||||||
|
8
umkaio.h
8
umkaio.h
@ -14,6 +14,10 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#if !defined (O_BINARY)
|
||||||
|
#define O_BINARY 0 // for Windows
|
||||||
|
#endif
|
||||||
|
|
||||||
struct umka_io {
|
struct umka_io {
|
||||||
const atomic_int *running;
|
const atomic_int *running;
|
||||||
pthread_t iot;
|
pthread_t iot;
|
||||||
@ -73,9 +77,9 @@ void
|
|||||||
io_close(struct umka_io *io);
|
io_close(struct umka_io *io);
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
io_read(int fd, void *buf, size_t count, struct umka_io *io);
|
io_read(int fd, void *buf, size_t count, const struct umka_io *io);
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
io_write(int fd, const void *buf, size_t count, struct umka_io *io);
|
io_write(int fd, const void *buf, size_t count, const struct umka_io *io);
|
||||||
|
|
||||||
#endif // UMKAIO_H_INCLUDED
|
#endif // UMKAIO_H_INCLUDED
|
||||||
|
4
vdisk.c
4
vdisk.c
@ -41,8 +41,8 @@ vdisk_adjust_cache_size(void *userdata, size_t suggested_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct vdisk*
|
struct vdisk*
|
||||||
vdisk_init(const char *fname, int adjust_cache_size, size_t cache_size,
|
vdisk_init(const char *fname, const int adjust_cache_size,
|
||||||
void *io) {
|
const size_t cache_size, const void *io) {
|
||||||
size_t fname_len = strlen(fname);
|
size_t fname_len = strlen(fname);
|
||||||
size_t dot_raw_len = strlen(RAW_SUFFIX);
|
size_t dot_raw_len = strlen(RAW_SUFFIX);
|
||||||
size_t dot_qcow2_len = strlen(QCOW2_SUFFIX);
|
size_t dot_qcow2_len = strlen(QCOW2_SUFFIX);
|
||||||
|
6
vdisk.h
6
vdisk.h
@ -19,11 +19,11 @@ struct vdisk {
|
|||||||
uint64_t sect_cnt;
|
uint64_t sect_cnt;
|
||||||
unsigned cache_size;
|
unsigned cache_size;
|
||||||
int adjust_cache_size;
|
int adjust_cache_size;
|
||||||
void *io;
|
const void *io;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vdisk*
|
struct vdisk*
|
||||||
vdisk_init(const char *fname, int adjust_cache_size, size_t cache_size,
|
vdisk_init(const char *fname, const int adjust_cache_size,
|
||||||
void *io);
|
const size_t cache_size, const void *io);
|
||||||
|
|
||||||
#endif // VDISK_H_INCLUDED
|
#endif // VDISK_H_INCLUDED
|
||||||
|
@ -197,7 +197,7 @@ vdisk_qcow2_write(void *userdata, void *buffer, off_t startsector,
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct vdisk*
|
struct vdisk*
|
||||||
vdisk_init_qcow2(const char *fname, struct umka_io *io) {
|
vdisk_init_qcow2(const char *fname, const struct umka_io *io) {
|
||||||
struct vdisk_qcow2 *d =
|
struct vdisk_qcow2 *d =
|
||||||
(struct vdisk_qcow2*)calloc(1, sizeof(struct vdisk_qcow2));
|
(struct vdisk_qcow2*)calloc(1, sizeof(struct vdisk_qcow2));
|
||||||
if (!d) {
|
if (!d) {
|
||||||
|
@ -17,6 +17,6 @@
|
|||||||
#define QCOW2_SUFFIX ".qcow2"
|
#define QCOW2_SUFFIX ".qcow2"
|
||||||
|
|
||||||
struct vdisk*
|
struct vdisk*
|
||||||
vdisk_init_qcow2(const char *fname, struct umka_io *io);
|
vdisk_init_qcow2(const char *fname, const struct umka_io *io);
|
||||||
|
|
||||||
#endif // VDISK_QCOW2_H_INCLUDED
|
#endif // VDISK_QCOW2_H_INCLUDED
|
||||||
|
@ -54,7 +54,7 @@ vdisk_raw_write(void *userdata, void *buffer, off_t startsector,
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct vdisk*
|
struct vdisk*
|
||||||
vdisk_init_raw(const char *fname, struct umka_io *io) {
|
vdisk_init_raw(const char *fname, const struct umka_io *io) {
|
||||||
int fd = open(fname, O_RDONLY | O_BINARY);
|
int fd = open(fname, O_RDONLY | O_BINARY);
|
||||||
if (!fd) {
|
if (!fd) {
|
||||||
printf("[vdisk.raw]: can't open file '%s': %s\n", fname, strerror(errno));
|
printf("[vdisk.raw]: can't open file '%s': %s\n", fname, strerror(errno));
|
||||||
|
@ -17,6 +17,6 @@
|
|||||||
#define RAW_SUFFIX ".raw"
|
#define RAW_SUFFIX ".raw"
|
||||||
|
|
||||||
struct vdisk*
|
struct vdisk*
|
||||||
vdisk_init_raw(const char *fname, struct umka_io *io);
|
vdisk_init_raw(const char *fname, const struct umka_io *io);
|
||||||
|
|
||||||
#endif // VDISK_RAW_H_INCLUDED
|
#endif // VDISK_RAW_H_INCLUDED
|
||||||
|
22
vnet.c
22
vnet.c
@ -22,8 +22,9 @@
|
|||||||
#include "umkart.h"
|
#include "umkart.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "vnet.h"
|
#include "vnet.h"
|
||||||
#include "vnet/tap.h"
|
#include "vnet/null.h"
|
||||||
#include "vnet/file.h"
|
#include "vnet/file.h"
|
||||||
|
#include "vnet/tap.h"
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -89,13 +90,16 @@ vnet_input_monitor(void *arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct vnet *
|
struct vnet *
|
||||||
vnet_init(enum vnet_type type) {
|
vnet_init(enum vnet_type type, const atomic_int *running) {
|
||||||
struct vnet *vnet;
|
struct vnet *vnet;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case VNET_FILE:
|
case VNET_DEVTYPE_NULL:
|
||||||
|
vnet = vnet_init_null();
|
||||||
|
break;
|
||||||
|
case VNET_DEVTYPE_FILE:
|
||||||
vnet = vnet_init_file();
|
vnet = vnet_init_file();
|
||||||
break;
|
break;
|
||||||
case VNET_TAP:
|
case VNET_DEVTYPE_TAP:
|
||||||
vnet = vnet_init_tap();
|
vnet = vnet_init_tap();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -107,6 +111,8 @@ vnet_init(enum vnet_type type) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vnet->running = running;
|
||||||
|
|
||||||
vnet->eth.net.link_state = ETH_LINK_FD + ETH_LINK_10M;
|
vnet->eth.net.link_state = ETH_LINK_FD + ETH_LINK_10M;
|
||||||
vnet->eth.net.hwacc = 0;
|
vnet->eth.net.hwacc = 0;
|
||||||
|
|
||||||
@ -128,9 +134,11 @@ vnet_init(enum vnet_type type) {
|
|||||||
// pthread_mutex_lock(&vnet->mutex);
|
// pthread_mutex_lock(&vnet->mutex);
|
||||||
|
|
||||||
kos_attach_int_handler(UMKA_IRQ_NETWORK, vnet_input, vnet);
|
kos_attach_int_handler(UMKA_IRQ_NETWORK, vnet_input, vnet);
|
||||||
fprintf(stderr, "[vnet] start input_monitor thread\n");
|
if (*running != UMKA_RUNNING_NEVER) {
|
||||||
pthread_t thread_input_monitor;
|
fprintf(stderr, "[vnet] start input_monitor thread\n");
|
||||||
pthread_create(&thread_input_monitor, NULL, vnet_input_monitor, vnet);
|
pthread_t thread_input_monitor;
|
||||||
|
pthread_create(&thread_input_monitor, NULL, vnet_input_monitor, vnet);
|
||||||
|
}
|
||||||
|
|
||||||
return vnet;
|
return vnet;
|
||||||
}
|
}
|
||||||
|
12
vnet.h
12
vnet.h
@ -10,28 +10,28 @@
|
|||||||
#ifndef VNET_H_INCLUDED
|
#ifndef VNET_H_INCLUDED
|
||||||
#define VNET_H_INCLUDED
|
#define VNET_H_INCLUDED
|
||||||
|
|
||||||
|
#include <stdatomic.h>
|
||||||
#include "umka.h"
|
#include "umka.h"
|
||||||
|
|
||||||
#define UMKA_VNET_NAME "umka%d"
|
|
||||||
#define VNET_BUFIN_CAP (NET_BUFFER_SIZE - offsetof(net_buff_t, data))
|
#define VNET_BUFIN_CAP (NET_BUFFER_SIZE - offsetof(net_buff_t, data))
|
||||||
|
|
||||||
enum vnet_type {
|
enum vnet_type {
|
||||||
VNET_FILE,
|
VNET_DEVTYPE_NULL,
|
||||||
VNET_TAP,
|
VNET_DEVTYPE_FILE,
|
||||||
|
VNET_DEVTYPE_TAP,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vnet {
|
struct vnet {
|
||||||
struct eth_device eth;
|
struct eth_device eth;
|
||||||
uint8_t bufin[VNET_BUFIN_CAP];
|
uint8_t bufin[VNET_BUFIN_CAP];
|
||||||
size_t bufin_len;
|
size_t bufin_len;
|
||||||
// pthread_cond_t cond;
|
|
||||||
// pthread_mutex_t mutex;
|
|
||||||
int fdin;
|
int fdin;
|
||||||
int fdout;
|
int fdout;
|
||||||
int input_processed;
|
int input_processed;
|
||||||
|
const atomic_int *running;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vnet *
|
struct vnet *
|
||||||
vnet_init(enum vnet_type type);
|
vnet_init(enum vnet_type type, const atomic_int *running);
|
||||||
|
|
||||||
#endif // VNET_H_INCLUDED
|
#endif // VNET_H_INCLUDED
|
||||||
|
78
vnet/null.c
Normal file
78
vnet/null.c
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
UMKa - User-Mode KolibriOS developer tools
|
||||||
|
vnet - virtual network card, null interface
|
||||||
|
|
||||||
|
Copyright (C) 2023 Ivan Baravy <dunkaist@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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_null(void) {
|
||||||
|
COVERAGE_ON();
|
||||||
|
COVERAGE_OFF();
|
||||||
|
}
|
||||||
|
|
||||||
|
static STDCALL void
|
||||||
|
vnet_reset_null(void) {
|
||||||
|
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_null(net_buff_t *buf) {
|
||||||
|
struct vnet *net;
|
||||||
|
__asm__ __inline__ __volatile__ (
|
||||||
|
""
|
||||||
|
: "=b"(net)
|
||||||
|
:
|
||||||
|
: "memory");
|
||||||
|
|
||||||
|
// dump_net_buff(buf);
|
||||||
|
buf->length = 0;
|
||||||
|
COVERAGE_OFF();
|
||||||
|
COVERAGE_ON();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct vnet *
|
||||||
|
vnet_init_null(void) {
|
||||||
|
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, "UMKNUL%d", 0); // FIXME: support more devices
|
||||||
|
vnet->eth.net.name = devname;
|
||||||
|
|
||||||
|
vnet->eth.net.unload = vnet_unload_null;
|
||||||
|
vnet->eth.net.reset = vnet_reset_null;
|
||||||
|
vnet->eth.net.transmit = vnet_transmit_null;
|
||||||
|
|
||||||
|
vnet->fdin = 0;
|
||||||
|
vnet->fdout = 0;
|
||||||
|
vnet->input_processed = 1;
|
||||||
|
|
||||||
|
memcpy(vnet->eth.mac, (uint8_t[]){0x80, 0x2b, 0xf9, 0x3b, 0x6c, 0xca},
|
||||||
|
sizeof(vnet->eth.mac));
|
||||||
|
|
||||||
|
return vnet;
|
||||||
|
}
|
16
vnet/null.h
Normal file
16
vnet/null.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
UMKa - User-Mode KolibriOS developer tools
|
||||||
|
vnet - virtual network card, null interface
|
||||||
|
|
||||||
|
Copyright (C) 2023 Ivan Baravy <dunkaist@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef VNET_NULL_H_INCLUDED
|
||||||
|
#define VNET_NULL_H_INCLUDED
|
||||||
|
|
||||||
|
struct vnet *
|
||||||
|
vnet_init_null(void);
|
||||||
|
|
||||||
|
#endif // VNET_NULL_H_INCLUDED
|
Loading…
Reference in New Issue
Block a user