diff --git a/src/tests/kits/net/new_stack/arp/arp.c b/src/tests/kits/net/new_stack/arp/arp.c new file mode 100644 index 0000000000..88ea4810b9 --- /dev/null +++ b/src/tests/kits/net/new_stack/arp/arp.c @@ -0,0 +1,129 @@ +/* ethernet.c - ethernet devices interface module + */ + +#include +#include +#include +#include + +#include +#include + +#include + +#include "net_stack.h" +#include "net_layer.h" + +status_t std_ops(int32 op, ...); + +struct net_layer_module_info nlmi; + +static struct net_stack_module_info *g_stack = NULL; + +// ------------------- +status_t init(void * params) +{ + status_t status; + net_layer *layer1, *layer2; + + layer2 = NULL; + status = B_NO_MEMORY; + + layer1 = malloc(sizeof(*layer1)); + if (!layer1) + goto error; + + layer1->name = "ethernet/arp"; + layer1->module = &nlmi; + + layer2 = malloc(sizeof(*layer2)); + if (!layer2) + goto error; + + layer2->name = "arp/ethernet"; + layer2->module = &nlmi; + + status = g_stack->register_layer(layer1); + return g_stack->register_layer(layer2); + +error:; + if (layer1) + free(layer1); + if (layer2) + free(layer2); + return status; +} + +status_t uninit(net_layer *me) +{ + printf("%s: uniniting layer\n", me->name); + + free(me); + return B_OK; +} + + +status_t enable(net_layer *me, bool enable) +{ + return B_OK; +} + + +status_t input_buffer(net_layer *me, net_buffer *buffer) +{ + if (!buffer) + return B_ERROR; + + // TODO! + return B_OK; +} + +status_t output_buffer(net_layer *me, net_buffer *buffer) +{ + if (!buffer) + return B_ERROR; + + // TODO! + return B_OK; +} + +// #pragma mark - + +// #pragma mark - + +status_t std_ops(int32 op, ...) +{ + switch(op) { + case B_MODULE_INIT: + printf("arp: B_MODULE_INIT\n"); + return get_module(NET_STACK_MODULE_NAME, (module_info **) &g_stack); + + case B_MODULE_UNINIT: + printf("arp: B_MODULE_UNINIT\n"); + put_module(NET_STACK_MODULE_NAME); + break; + + default: + return B_ERROR; + } + return B_OK; +} + +struct net_layer_module_info nlmi = { + { + NET_LAYER_MODULE_ROOT "protocols/arp/v0", + 0, + std_ops + }, + + init, + uninit, + enable, + output_buffer, + input_buffer +}; + +_EXPORT module_info *modules[] = { + (module_info*) &nlmi, // net_layer_module_info + NULL +}; diff --git a/src/tests/kits/net/new_stack/arp/arp_module_x86.proj b/src/tests/kits/net/new_stack/arp/arp_module_x86.proj new file mode 100644 index 0000000000..87305745b1 Binary files /dev/null and b/src/tests/kits/net/new_stack/arp/arp_module_x86.proj differ diff --git a/src/tests/kits/net/new_stack/ethernet/ethernet.c b/src/tests/kits/net/new_stack/ethernet/ethernet.c index 6cd7f3b3b6..76e74e5d57 100644 --- a/src/tests/kits/net/new_stack/ethernet/ethernet.c +++ b/src/tests/kits/net/new_stack/ethernet/ethernet.c @@ -5,14 +5,16 @@ #include #include #include +#include #include #include +#include #include #include "net_stack.h" -#include "net_interface.h" +#include "net_layer.h" enum { ETHER_GETADDR = B_DEVICE_OP_CODES_END, @@ -24,11 +26,12 @@ enum { ETHER_GETFRAMESIZE }; -typedef struct ethernet_interface { - ifnet_t ifnet; - int fd; - int max_frame_size; -} ethernet_interface; +typedef struct ethernet_device_layer { + net_layer layer; + int fd; + int max_frame_size; + volatile thread_id reader_thread; +} ethernet_device_layer; #define ETHER_ADDR_LEN 6 /* Ethernet address length */ #define ETHER_TYPE_LEN 2 /* Ethernet type field length */ @@ -46,9 +49,10 @@ typedef struct ether_addr { status_t lookup_devices(char *root, void *cookie); status_t register_device(const char *path, void *cookie); +status_t device_reader(void *args); status_t std_ops(int32 op, ...); -struct net_interface_module_info nimi; +struct net_layer_module_info nlmi; static struct net_stack_module_info *g_stack = NULL; @@ -59,92 +63,79 @@ status_t init(void * params) return lookup_devices("/dev/net", params); } -status_t uninit(ifnet_t *iface) +status_t uninit(net_layer *me) { - ethernet_interface *ei = (ethernet_interface *) iface; + ethernet_device_layer *edl = (ethernet_device_layer *) me; - printf("ethernet: uniniting %s interface\n", iface->if_name); + printf("%s: uniniting layer\n", me->name); - free(iface->if_name); - close(ei->fd); + close(edl->fd); + + free(me->name); + free(me); return B_OK; } -status_t up(ifnet_t *iface) +status_t enable(net_layer *me, bool enable) { - return B_ERROR; + ethernet_device_layer *edl = (ethernet_device_layer *) me; + + if (enable) { + // enable this layer + thread_id tid; + char name[B_OS_NAME_LENGTH * 2]; + + if (edl->reader_thread != -1) + // already up + return B_OK; + + strncpy(name, me->name, sizeof(name)); + strncat(name, " reader", sizeof(name)); + tid = spawn_kernel_thread(device_reader, name, B_NORMAL_PRIORITY, me); + if (tid < 0) { + printf("%s: failed to start device reader thread -> %d [%s]\n", + me->name, (int) tid, strerror(tid)); + return tid; + }; + + edl->reader_thread = tid; + return resume_thread(tid); + + } else { + + status_t dummy; + + // disable this layer + if (edl->reader_thread == -1) + // already down + return B_OK; + + send_signal_etc(edl->reader_thread, SIGTERM, 0); + wait_for_thread(edl->reader_thread, &dummy); + printf("%s: device reader stopped.\n", me->name); + edl->reader_thread = -1; + return B_OK; + }; + + return B_OK; } -status_t down(ifnet_t *iface) -{ - return B_ERROR; -} - - -status_t send(ifnet_t *iface, net_buffer *buffer) +status_t output_buffer(net_layer *me, net_buffer *buffer) { if (!buffer) return B_ERROR; - + // TODO! - return B_OK; -} + printf("%s: output_buffer:\n", me->name); + g_stack->dump_buffer(buffer); - -status_t receive(ifnet_t *iface, net_buffer **received_buffer) -{ - ethernet_interface *ei = (ethernet_interface *) iface; - net_buffer *buffer; - void *frame; - size_t len; - ssize_t sz; - - len = iface->if_mtu; - frame = malloc(len); - if (!frame) - return B_NO_MEMORY; - - buffer = g_stack->new_buffer(); - if (!buffer) { - free(frame); - return B_NO_MEMORY; - }; - - sz = read(ei->fd, frame, len); - if (sz >= B_OK) { - g_stack->add_to_buffer(buffer, 0, frame, sz, (buffer_chunk_free_func) free); - *received_buffer = buffer; - return sz; - }; - - free(frame); g_stack->delete_buffer(buffer, false); - return sz; -} - -status_t control(ifnet_t *iface, int opcode, void *arg) { return -1; } - -status_t get_hardware_address(ifnet_t *iface, net_interface_hwaddr *hwaddr) { return -1; } -status_t get_multicast_addresses(ifnet_t *iface, net_interface_hwaddr **hwaddr, int nb_addresses) { return -1; } -status_t set_multicast_addresses(ifnet_t *iface, net_interface_hwaddr *hwaddr, int nb_addresses) { return -1; } - -status_t set_mtu(ifnet_t *iface, uint32 mtu) -{ - ethernet_interface *ei = (ethernet_interface *) iface; - - if (mtu > ei->max_frame_size) - // hardware constraint always win! - mtu = ei->max_frame_size; - - ei->ifnet.if_mtu = mtu; return B_OK; } -status_t set_promiscuous(ifnet_t *iface, bool enable) { return -1; } -status_t set_media(ifnet_t *iface, uint32 media) { return -1; } // #pragma mark - @@ -178,8 +169,9 @@ status_t lookup_devices(char *root, void *cookie) if (S_ISDIR(st.st_mode)) status = lookup_devices(path, cookie); else if (S_ISCHR(st.st_mode)) { // char device = driver! - if (strcmp(de->d_name, "stack") == 0 || // OBOS stack driver - strcmp(de->d_name, "api") == 0) // BONE stack driver + if (strcmp(de->d_name, "stack") == 0 || // OBOS stack driver + strcmp(de->d_name, "server") == 0 || // OBOS server driver + strcmp(de->d_name, "api") == 0) // BONE stack driver continue; // skip pseudo-entries status = register_device(path, cookie); @@ -194,16 +186,16 @@ status_t lookup_devices(char *root, void *cookie) status_t register_device(const char *path, void *cookie) { - ifnet_t *iface; - ethernet_interface *ei; + ethernet_device_layer *edl; int frame_size; ether_addr_t mac_address; int fd; status_t status; + char *name; fd = open(path, O_RDWR); if (fd < B_OK) { - printf("ethernet: Unable to open(%s) -> %d [%s]. Skipping...\n", path, + printf("ethernet: Unable to open %s device -> %d [%s]. Skipping...\n", path, fd, strerror(fd)); return fd; }; @@ -211,7 +203,7 @@ status_t register_device(const char *path, void *cookie) // Init the network card status = ioctl(fd, ETHER_INIT, NULL, 0); if (status < B_OK) { - printf("ethernet: Failed to init %s: %ld [%s]. Skipping...\n", path, + printf("ethernet: Failed to init %s device -> %ld [%s]. Skipping...\n", path, status, strerror(status)); close(fd); return status; @@ -220,7 +212,7 @@ status_t register_device(const char *path, void *cookie) // get the MAC address... status = ioctl(fd, ETHER_GETADDR, &mac_address, 6); if (status < B_OK) { - printf("ethernet: Failed to get %s MAC address: %ld [%s]. Skipping...\n", + printf("ethernet: Failed to get %s device MAC address -> %ld [%s]. Skipping...\n", path, status, strerror(status)); close(fd); return status; @@ -230,37 +222,79 @@ status_t register_device(const char *path, void *cookie) status = ioctl(fd, ETHER_GETFRAMESIZE, &frame_size, sizeof(frame_size)); if (status < B_OK) { frame_size = ETHERMTU; - printf("ethernet: %s device don't support IF_GETFRAMESIZE; defaulting to %d\n", + printf("ethernet: %s device don't support ETHER_GETFRAMESIZE; defaulting to %d\n", path, frame_size); }; - printf("ethernet: interface '%s':\n" - "\tMAC address: %02x:%02x:%02x:%02x:%02x:%02x\n" - "\tMTU: %d bytes\n", + printf("ethernet: Found device '%s': MAC address: %02x:%02x:%02x:%02x:%02x:%02x, MTU: %d bytes\n", path, mac_address.byte[0], mac_address.byte[1], mac_address.byte[2], mac_address.byte[3], mac_address.byte[4], mac_address.byte[5], frame_size); - ei = (ethernet_interface *) malloc(sizeof(*ei)); - if (!ei) { + edl = malloc(sizeof(*edl)); + if (!edl) { close(fd); return B_NO_MEMORY; }; - ei->fd = fd; - ei->max_frame_size = frame_size; + edl->fd = fd; + edl->max_frame_size = frame_size; + edl->reader_thread = -1; - iface = &ei->ifnet; + name = malloc(strlen("ethernet/") + strlen(path)); + strcpy(name, "ethernet/"); + strcat(name, path + strlen("/dev/net/")); - iface->if_name = strdup(path); - iface->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST); - iface->if_type = 0x20; // IFT_ETHER; - iface->if_mtu = frame_size; + edl->layer.name = name; + edl->layer.module = &nlmi; - iface->module = &nimi; + return g_stack->register_layer(&edl->layer); +} + +// ---------------------------------------------------- +status_t device_reader(void *args) +{ + net_layer *me = args; + ethernet_device_layer *edl = (ethernet_device_layer *) me; + net_buffer *buffer; + status_t status; + void *frame; + ssize_t sz; + + printf("%s: device reader started.\n", me->name); + + status = B_OK; + while(1) { + frame = malloc(edl->max_frame_size); + if (!frame) { + status = B_NO_MEMORY; + break; + }; + + // read on frame at time + sz = read(edl->fd, frame, edl->max_frame_size); + if (sz >= B_OK) { + buffer = g_stack->new_buffer(); + if (!buffer) { + free(frame); + status = B_NO_MEMORY; + break; + }; + + g_stack->add_to_buffer(buffer, 0, frame, sz, (buffer_chunk_free_func) free); - return g_stack->register_interface(iface); + printf("%s: input buffer:\n", me->name); + g_stack->dump_buffer(buffer); + + if (g_stack->push_buffer_up(me, buffer) != B_OK) + // nobody above us *eat* this buffer, so we drop it ourself :-( + g_stack->delete_buffer(buffer, false); + }; + }; + + edl->reader_thread = -1; + return status; } // #pragma mark - @@ -283,29 +317,21 @@ status_t std_ops(int32 op, ...) return B_OK; } -struct net_interface_module_info nimi = { +struct net_layer_module_info nlmi = { { - NET_INTERFACE_MODULE_ROOT "ethernet/v0", + NET_LAYER_MODULE_ROOT "interfaces/ethernet", 0, std_ops }, init, uninit, - up, - down, - send, - receive, - control, - get_hardware_address, - get_multicast_addresses, - set_multicast_addresses, - set_mtu, - set_promiscuous, - set_media + enable, + output_buffer, + NULL // interface layer: no input_buffer }; _EXPORT module_info *modules[] = { - (module_info*) &nimi, // net_interface_module_info + (module_info*) &nlmi, // net_layer_module_info NULL }; diff --git a/src/tests/kits/net/new_stack/ethernet/ethernet_module_x86.proj b/src/tests/kits/net/new_stack/ethernet/ethernet_module_x86.proj index 5f82df67c1..d19b14e43e 100644 Binary files a/src/tests/kits/net/new_stack/ethernet/ethernet_module_x86.proj and b/src/tests/kits/net/new_stack/ethernet/ethernet_module_x86.proj differ diff --git a/src/tests/kits/net/new_stack/loopback/loopback.c b/src/tests/kits/net/new_stack/loopback/loopback.c index b9f8b23f22..15821559dc 100644 --- a/src/tests/kits/net/new_stack/loopback/loopback.c +++ b/src/tests/kits/net/new_stack/loopback/loopback.c @@ -1,102 +1,63 @@ -/* loopback.c - loopback device +/* loopback.c - loopback interface module */ #include #include +#include +#include + +#include +#include + +#include #include "net_stack.h" -#include "net_interface.h" +#include "net_layer.h" -#define LOOPBACK_MTU 16384 // can be as large as we want +status_t std_ops(int32 op, ...); + +struct net_layer_module_info nlmi; + +static struct net_stack_module_info *g_stack = NULL; -typedef struct loopback_interface { - ifnet_t ifnet; - net_buffer_queue *queue; -} loopback_interface; - - -status_t std_ops(int32 op, ...); - -struct net_interface_module_info nimi; - -struct net_stack_module_info *g_stack = NULL; - +// ------------------- status_t init(void * params) { - ifnet_t * iface; - loopback_interface *li; - - li = (loopback_interface *) malloc(sizeof(*li)); - if (!li) - return B_NO_MEMORY; + net_layer *layer; - // create loopback fifo queue, to keep packets *sent* - li->queue = g_stack->new_buffer_queue(64*LOOPBACK_MTU); + layer = malloc(sizeof(*layer)); + if (!layer) + return B_NO_MEMORY; - - iface = &li->ifnet; - iface->if_name = "loopback"; - iface->if_flags = (IFF_LOOPBACK | IFF_NOARP); - iface->if_type = 0x10; //IFT_LOOP - iface->if_mtu = LOOPBACK_MTU; + layer->name = "*/loopback"; + layer->module = &nlmi; - // never forget to store a pointer to us, otherwise datalink layer can't call us - iface->module = &nimi; - - return g_stack->register_interface(iface); + return g_stack->register_layer(layer); } -status_t uninit(ifnet_t *iface) +status_t uninit(net_layer *me) { - loopback_interface *li = (loopback_interface *) iface; - - printf("loopback: uniniting %s interface\n", iface->if_name); - return g_stack->delete_buffer_queue(li->queue); -} - -status_t up(ifnet_t *iface) -{ - return B_ERROR; + printf("%s: uniniting layer\n", me->name); + free(me); + return B_OK; } -status_t down(ifnet_t *iface) +status_t enable(net_layer *me, bool enable) { - return B_ERROR; + return B_OK; } -status_t send(ifnet_t *iface, net_buffer *buffer) +status_t output_buffer(net_layer *me, net_buffer *buffer) { - loopback_interface *li = (loopback_interface *) iface; - if (!buffer) return B_ERROR; - - return g_stack->enqueue_buffer(li->queue, buffer); + + return g_stack->push_buffer_up(me, buffer); } - -status_t receive(ifnet_t *iface, net_buffer **buffer) -{ - loopback_interface *li = (loopback_interface *) iface; - - return g_stack->dequeue_buffer(li->queue, buffer, B_INFINITE_TIMEOUT, false); -} - - -status_t control(ifnet_t *iface, int opcode, void *arg) { return -1; } - -status_t get_hardware_address(ifnet_t *iface, net_interface_hwaddr *hwaddr) { return -1; } -status_t get_multicast_addresses(ifnet_t *iface, net_interface_hwaddr **hwaddr, int nb_addresses) { return -1; } -status_t set_multicast_addresses(ifnet_t *iface, net_interface_hwaddr *hwaddr, int nb_addresses) { return -1; } - -status_t set_mtu(ifnet_t *iface, uint32 mtu) { return -1; } -status_t set_promiscuous(ifnet_t *iface, bool enable) { return -1; } -status_t set_media(ifnet_t *iface, uint32 media) { return -1; } - - // #pragma mark - status_t std_ops(int32 op, ...) @@ -117,29 +78,21 @@ status_t std_ops(int32 op, ...) return B_OK; } -struct net_interface_module_info nimi = { +struct net_layer_module_info nlmi = { { - NET_INTERFACE_MODULE_ROOT "loopback", + NET_LAYER_MODULE_ROOT "interfaces/loopback", 0, std_ops }, init, uninit, - up, - down, - send, - receive, - control, - get_hardware_address, - get_multicast_addresses, - set_multicast_addresses, - set_mtu, - set_promiscuous, - set_media + enable, + output_buffer, + NULL // interface layer: no input_buffer }; _EXPORT module_info *modules[] = { - (module_info*) &nimi, // net_interface_module_info + (module_info*) &nlmi, // net_layer_module_info NULL }; diff --git a/src/tests/kits/net/new_stack/loopback/loopback_module_x86.proj b/src/tests/kits/net/new_stack/loopback/loopback_module_x86.proj index 4b1cc729df..9d5bb19c6c 100644 Binary files a/src/tests/kits/net/new_stack/loopback/loopback_module_x86.proj and b/src/tests/kits/net/new_stack/loopback/loopback_module_x86.proj differ diff --git a/src/tests/kits/net/new_stack/memory_pool/memory_pool_module_x86.proj b/src/tests/kits/net/new_stack/memory_pool/memory_pool_module_x86.proj index a9e246e336..9ccc575473 100644 Binary files a/src/tests/kits/net/new_stack/memory_pool/memory_pool_module_x86.proj and b/src/tests/kits/net/new_stack/memory_pool/memory_pool_module_x86.proj differ diff --git a/src/tests/kits/net/new_stack/stack/stack_module_x86.proj b/src/tests/kits/net/new_stack/stack/stack_module_x86.proj index 55a0ae7018..c34e47d5b5 100644 Binary files a/src/tests/kits/net/new_stack/stack/stack_module_x86.proj and b/src/tests/kits/net/new_stack/stack/stack_module_x86.proj differ