Small new_stack progress...
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4079 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -12,7 +12,6 @@
|
|||||||
#include <Drivers.h>
|
#include <Drivers.h>
|
||||||
|
|
||||||
#include "net_stack.h"
|
#include "net_stack.h"
|
||||||
#include "net_layer.h"
|
|
||||||
|
|
||||||
status_t std_ops(int32 op, ...);
|
status_t std_ops(int32 op, ...);
|
||||||
|
|
||||||
@@ -21,44 +20,16 @@ struct net_layer_module_info nlmi;
|
|||||||
static struct net_stack_module_info *g_stack = NULL;
|
static struct net_stack_module_info *g_stack = NULL;
|
||||||
|
|
||||||
// -------------------
|
// -------------------
|
||||||
status_t init(void * params)
|
status_t init(net_layer *me)
|
||||||
{
|
{
|
||||||
status_t status;
|
printf("%s: initing layer\n", me->name);
|
||||||
net_layer *layer1, *layer2;
|
return B_OK;
|
||||||
|
|
||||||
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)
|
status_t uninit(net_layer *me)
|
||||||
{
|
{
|
||||||
printf("%s: uniniting layer\n", me->name);
|
printf("%s: uniniting layer\n", me->name);
|
||||||
|
|
||||||
free(me);
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,9 +65,30 @@ status_t output_buffer(net_layer *me, net_buffer *buffer)
|
|||||||
status_t std_ops(int32 op, ...)
|
status_t std_ops(int32 op, ...)
|
||||||
{
|
{
|
||||||
switch(op) {
|
switch(op) {
|
||||||
case B_MODULE_INIT:
|
case B_MODULE_INIT: {
|
||||||
|
status_t status;
|
||||||
|
net_layer *layer1, *layer2;
|
||||||
|
|
||||||
printf("arp: B_MODULE_INIT\n");
|
printf("arp: B_MODULE_INIT\n");
|
||||||
return get_module(NET_STACK_MODULE_NAME, (module_info **) &g_stack);
|
status = get_module(NET_STACK_MODULE_NAME, (module_info **) &g_stack);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = g_stack->register_layer("ethernet/arp", &nlmi, NULL, &layer1);
|
||||||
|
if (status != B_OK)
|
||||||
|
goto error1;
|
||||||
|
|
||||||
|
status = g_stack->register_layer("arp/ethernet", &nlmi, NULL, &layer2);
|
||||||
|
if (status != B_OK)
|
||||||
|
goto error2;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
error2:
|
||||||
|
g_stack->unregister_layer(layer1);
|
||||||
|
error1:
|
||||||
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
case B_MODULE_UNINIT:
|
case B_MODULE_UNINIT:
|
||||||
printf("arp: B_MODULE_UNINIT\n");
|
printf("arp: B_MODULE_UNINIT\n");
|
||||||
@@ -111,7 +103,7 @@ status_t std_ops(int32 op, ...)
|
|||||||
|
|
||||||
struct net_layer_module_info nlmi = {
|
struct net_layer_module_info nlmi = {
|
||||||
{
|
{
|
||||||
NET_LAYER_MODULE_ROOT "protocols/arp/v0",
|
NET_LAYER_MODULES_ROOT "protocols/arp/v0",
|
||||||
0,
|
0,
|
||||||
std_ops
|
std_ops
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
#include <Drivers.h>
|
#include <Drivers.h>
|
||||||
|
|
||||||
#include "net_stack.h"
|
#include "net_stack.h"
|
||||||
#include "net_layer.h"
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ETHER_GETADDR = B_DEVICE_OP_CODES_END,
|
ETHER_GETADDR = B_DEVICE_OP_CODES_END,
|
||||||
@@ -26,12 +25,11 @@ enum {
|
|||||||
ETHER_GETFRAMESIZE
|
ETHER_GETFRAMESIZE
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ethernet_device_layer {
|
typedef struct ethernet_device {
|
||||||
net_layer layer;
|
|
||||||
int fd;
|
int fd;
|
||||||
int max_frame_size;
|
int max_frame_size;
|
||||||
volatile thread_id reader_thread;
|
volatile thread_id reader_thread;
|
||||||
} ethernet_device_layer;
|
} ethernet_device;
|
||||||
|
|
||||||
#define ETHER_ADDR_LEN 6 /* Ethernet address length */
|
#define ETHER_ADDR_LEN 6 /* Ethernet address length */
|
||||||
#define ETHER_TYPE_LEN 2 /* Ethernet type field length */
|
#define ETHER_TYPE_LEN 2 /* Ethernet type field length */
|
||||||
@@ -58,21 +56,20 @@ static struct net_stack_module_info *g_stack = NULL;
|
|||||||
|
|
||||||
|
|
||||||
// -------------------
|
// -------------------
|
||||||
status_t init(void * params)
|
status_t init(net_layer *me)
|
||||||
{
|
{
|
||||||
return lookup_devices("/dev/net", params);
|
printf("%s: initing layer\n", me->name);
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t uninit(net_layer *me)
|
status_t uninit(net_layer *me)
|
||||||
{
|
{
|
||||||
ethernet_device_layer *edl = (ethernet_device_layer *) me;
|
ethernet_device *ed = me->cookie;
|
||||||
|
|
||||||
printf("%s: uniniting layer\n", me->name);
|
printf("%s: uniniting layer\n", me->name);
|
||||||
|
|
||||||
close(edl->fd);
|
close(ed->fd);
|
||||||
|
free(me->cookie);
|
||||||
free(me->name);
|
|
||||||
free(me);
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -80,14 +77,14 @@ status_t uninit(net_layer *me)
|
|||||||
|
|
||||||
status_t enable(net_layer *me, bool enable)
|
status_t enable(net_layer *me, bool enable)
|
||||||
{
|
{
|
||||||
ethernet_device_layer *edl = (ethernet_device_layer *) me;
|
ethernet_device *ed = me->cookie;
|
||||||
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
// enable this layer
|
// enable this layer
|
||||||
thread_id tid;
|
thread_id tid;
|
||||||
char name[B_OS_NAME_LENGTH * 2];
|
char name[B_OS_NAME_LENGTH * 2];
|
||||||
|
|
||||||
if (edl->reader_thread != -1)
|
if (ed->reader_thread != -1)
|
||||||
// already up
|
// already up
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
@@ -100,7 +97,7 @@ status_t enable(net_layer *me, bool enable)
|
|||||||
return tid;
|
return tid;
|
||||||
};
|
};
|
||||||
|
|
||||||
edl->reader_thread = tid;
|
ed->reader_thread = tid;
|
||||||
return resume_thread(tid);
|
return resume_thread(tid);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -108,14 +105,14 @@ status_t enable(net_layer *me, bool enable)
|
|||||||
status_t dummy;
|
status_t dummy;
|
||||||
|
|
||||||
// disable this layer
|
// disable this layer
|
||||||
if (edl->reader_thread == -1)
|
if (ed->reader_thread == -1)
|
||||||
// already down
|
// already down
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
send_signal_etc(edl->reader_thread, SIGTERM, 0);
|
send_signal_etc(ed->reader_thread, SIGTERM, 0);
|
||||||
wait_for_thread(edl->reader_thread, &dummy);
|
wait_for_thread(ed->reader_thread, &dummy);
|
||||||
printf("%s: device reader stopped.\n", me->name);
|
printf("%s: device reader stopped.\n", me->name);
|
||||||
edl->reader_thread = -1;
|
ed->reader_thread = -1;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -186,7 +183,7 @@ status_t lookup_devices(char *root, void *cookie)
|
|||||||
|
|
||||||
status_t register_device(const char *path, void *cookie)
|
status_t register_device(const char *path, void *cookie)
|
||||||
{
|
{
|
||||||
ethernet_device_layer *edl;
|
ethernet_device *ed;
|
||||||
int frame_size;
|
int frame_size;
|
||||||
ether_addr_t mac_address;
|
ether_addr_t mac_address;
|
||||||
int fd;
|
int fd;
|
||||||
@@ -232,32 +229,29 @@ status_t register_device(const char *path, void *cookie)
|
|||||||
mac_address.byte[2], mac_address.byte[3],
|
mac_address.byte[2], mac_address.byte[3],
|
||||||
mac_address.byte[4], mac_address.byte[5], frame_size);
|
mac_address.byte[4], mac_address.byte[5], frame_size);
|
||||||
|
|
||||||
edl = malloc(sizeof(*edl));
|
ed = malloc(sizeof(*ed));
|
||||||
if (!edl) {
|
if (!ed) {
|
||||||
close(fd);
|
close(fd);
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
};
|
};
|
||||||
|
|
||||||
edl->fd = fd;
|
ed->fd = fd;
|
||||||
edl->max_frame_size = frame_size;
|
ed->max_frame_size = frame_size;
|
||||||
edl->reader_thread = -1;
|
ed->reader_thread = -1;
|
||||||
|
|
||||||
name = malloc(strlen("ethernet/") + strlen(path));
|
name = malloc(strlen("ethernet/") + strlen(path));
|
||||||
strcpy(name, "ethernet/");
|
strcpy(name, "ethernet/");
|
||||||
strcat(name, path + strlen("/dev/net/"));
|
strcat(name, path + strlen("/dev/net/"));
|
||||||
|
|
||||||
edl->layer.name = name;
|
return g_stack->register_layer(name, &nlmi, ed, NULL);
|
||||||
edl->layer.module = &nlmi;
|
|
||||||
|
|
||||||
return g_stack->register_layer(&edl->layer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------
|
// ----------------------------------------------------
|
||||||
status_t device_reader(void *args)
|
status_t device_reader(void *args)
|
||||||
{
|
{
|
||||||
net_layer *me = args;
|
net_layer *me = args;
|
||||||
ethernet_device_layer *edl = (ethernet_device_layer *) me;
|
ethernet_device *ed = (ethernet_device *) me->cookie;
|
||||||
net_buffer *buffer;
|
net_buffer *buffer;
|
||||||
status_t status;
|
status_t status;
|
||||||
void *frame;
|
void *frame;
|
||||||
ssize_t sz;
|
ssize_t sz;
|
||||||
@@ -266,14 +260,14 @@ status_t device_reader(void *args)
|
|||||||
|
|
||||||
status = B_OK;
|
status = B_OK;
|
||||||
while(1) {
|
while(1) {
|
||||||
frame = malloc(edl->max_frame_size);
|
frame = malloc(ed->max_frame_size);
|
||||||
if (!frame) {
|
if (!frame) {
|
||||||
status = B_NO_MEMORY;
|
status = B_NO_MEMORY;
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
// read on frame at time
|
// read on frame at time
|
||||||
sz = read(edl->fd, frame, edl->max_frame_size);
|
sz = read(ed->fd, frame, ed->max_frame_size);
|
||||||
if (sz >= B_OK) {
|
if (sz >= B_OK) {
|
||||||
buffer = g_stack->new_buffer();
|
buffer = g_stack->new_buffer();
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
@@ -293,7 +287,7 @@ status_t device_reader(void *args)
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
edl->reader_thread = -1;
|
ed->reader_thread = -1;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,9 +296,17 @@ status_t device_reader(void *args)
|
|||||||
status_t std_ops(int32 op, ...)
|
status_t std_ops(int32 op, ...)
|
||||||
{
|
{
|
||||||
switch(op) {
|
switch(op) {
|
||||||
case B_MODULE_INIT:
|
case B_MODULE_INIT: {
|
||||||
|
status_t status;
|
||||||
|
|
||||||
printf("ethernet: B_MODULE_INIT\n");
|
printf("ethernet: B_MODULE_INIT\n");
|
||||||
return get_module(NET_STACK_MODULE_NAME, (module_info **) &g_stack);
|
status = get_module(NET_STACK_MODULE_NAME, (module_info **) &g_stack);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
lookup_devices("/dev/net", NULL);
|
||||||
|
return B_OK;
|
||||||
|
};
|
||||||
|
|
||||||
case B_MODULE_UNINIT:
|
case B_MODULE_UNINIT:
|
||||||
printf("ethernet: B_MODULE_UNINIT\n");
|
printf("ethernet: B_MODULE_UNINIT\n");
|
||||||
@@ -319,7 +321,7 @@ status_t std_ops(int32 op, ...)
|
|||||||
|
|
||||||
struct net_layer_module_info nlmi = {
|
struct net_layer_module_info nlmi = {
|
||||||
{
|
{
|
||||||
NET_LAYER_MODULE_ROOT "interfaces/ethernet",
|
NET_LAYER_MODULES_ROOT "interfaces/ethernet",
|
||||||
0,
|
0,
|
||||||
std_ops
|
std_ops
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
#include <Drivers.h>
|
#include <Drivers.h>
|
||||||
|
|
||||||
#include "net_stack.h"
|
#include "net_stack.h"
|
||||||
#include "net_layer.h"
|
|
||||||
|
|
||||||
status_t std_ops(int32 op, ...);
|
status_t std_ops(int32 op, ...);
|
||||||
|
|
||||||
@@ -22,24 +21,15 @@ static struct net_stack_module_info *g_stack = NULL;
|
|||||||
|
|
||||||
|
|
||||||
// -------------------
|
// -------------------
|
||||||
status_t init(void * params)
|
status_t init(net_layer *me)
|
||||||
{
|
{
|
||||||
net_layer *layer;
|
printf("%s: initing layer\n", me->name);
|
||||||
|
return B_OK;
|
||||||
layer = malloc(sizeof(*layer));
|
|
||||||
if (!layer)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
layer->name = "*/loopback";
|
|
||||||
layer->module = &nlmi;
|
|
||||||
|
|
||||||
return g_stack->register_layer(layer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t uninit(net_layer *me)
|
status_t uninit(net_layer *me)
|
||||||
{
|
{
|
||||||
printf("%s: uniniting layer\n", me->name);
|
printf("loopback: uniniting layer\n");
|
||||||
free(me);
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,9 +53,16 @@ status_t output_buffer(net_layer *me, net_buffer *buffer)
|
|||||||
status_t std_ops(int32 op, ...)
|
status_t std_ops(int32 op, ...)
|
||||||
{
|
{
|
||||||
switch(op) {
|
switch(op) {
|
||||||
case B_MODULE_INIT:
|
case B_MODULE_INIT: {
|
||||||
|
status_t status;
|
||||||
|
|
||||||
printf("loopback: B_MODULE_INIT\n");
|
printf("loopback: B_MODULE_INIT\n");
|
||||||
return get_module(NET_STACK_MODULE_NAME, (module_info **) &g_stack);
|
status = get_module(NET_STACK_MODULE_NAME, (module_info **) &g_stack);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
return g_stack->register_layer("*/loopback", &nlmi, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
case B_MODULE_UNINIT:
|
case B_MODULE_UNINIT:
|
||||||
printf("loopback: B_MODULE_UNINIT\n");
|
printf("loopback: B_MODULE_UNINIT\n");
|
||||||
@@ -80,7 +77,7 @@ status_t std_ops(int32 op, ...)
|
|||||||
|
|
||||||
struct net_layer_module_info nlmi = {
|
struct net_layer_module_info nlmi = {
|
||||||
{
|
{
|
||||||
NET_LAYER_MODULE_ROOT "interfaces/loopback",
|
NET_LAYER_MODULES_ROOT "interfaces/loopback",
|
||||||
0,
|
0,
|
||||||
std_ops
|
std_ops
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -68,6 +68,11 @@ int test_buffer()
|
|||||||
|
|
||||||
g_stack->dump_buffer(buffer);
|
g_stack->dump_buffer(buffer);
|
||||||
|
|
||||||
|
printf("Removing 61 bytes at offset 4...\n");
|
||||||
|
g_stack->remove_from_buffer(buffer, 4, 61);
|
||||||
|
|
||||||
|
g_stack->dump_buffer(buffer);
|
||||||
|
|
||||||
len = g_stack->read_buffer(buffer, 2, data, sizeof(data));
|
len = g_stack->read_buffer(buffer, 2, data, sizeof(data));
|
||||||
data[len] = 0;
|
data[len] = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -29,8 +29,40 @@ typedef int benaphore;
|
|||||||
#define lock_benaphore(a)
|
#define lock_benaphore(a)
|
||||||
#define unlock_benaphore(a)
|
#define unlock_benaphore(a)
|
||||||
|
|
||||||
// Networking layer(s) definition
|
// Networking layer(s) definitions
|
||||||
#include "net_layer.h"
|
typedef struct net_layer net_layer;
|
||||||
|
#define NET_LAYER_MODULES_ROOT "network/layers/"
|
||||||
|
|
||||||
|
typedef struct net_layer_module_info {
|
||||||
|
module_info info;
|
||||||
|
|
||||||
|
status_t (*init)(net_layer *me);
|
||||||
|
status_t (*uninit)(net_layer *me);
|
||||||
|
status_t (*enable)(net_layer *me, bool enable);
|
||||||
|
status_t (*input_buffer)(net_layer *me, struct net_buffer *buffer);
|
||||||
|
status_t (*output_buffer)(net_layer *me, struct net_buffer *buffer);
|
||||||
|
} net_layer_module_info;
|
||||||
|
|
||||||
|
struct net_layer {
|
||||||
|
struct net_layer *next;
|
||||||
|
char *name;
|
||||||
|
net_layer_module_info *module;
|
||||||
|
void *cookie;
|
||||||
|
struct net_layer **layers_above;
|
||||||
|
struct net_layer **layers_below;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Networking attributs
|
||||||
|
enum {
|
||||||
|
NET_ATTRIBUT_BOOL,
|
||||||
|
NET_ATTRIBUT_BYTE,
|
||||||
|
NET_ATTRIBUT_INT16,
|
||||||
|
NET_ATTRIBUT_INT32,
|
||||||
|
NET_ATTRIBUT_INT64,
|
||||||
|
NET_ATTRIBUT_DATA,
|
||||||
|
NET_ATTRIBUT_STRING,
|
||||||
|
NET_ATTRIBUT_POINTER
|
||||||
|
};
|
||||||
|
|
||||||
// Network stack main module definition
|
// Network stack main module definition
|
||||||
|
|
||||||
@@ -48,9 +80,14 @@ struct net_stack_module_info {
|
|||||||
* Net layers handling
|
* Net layers handling
|
||||||
*/
|
*/
|
||||||
|
|
||||||
status_t (*register_layer)(net_layer *layer);
|
status_t (*register_layer)(const char *name, net_layer_module_info *module, void *cookie, net_layer **me);
|
||||||
status_t (*unregister_layer)(net_layer *layer);
|
status_t (*unregister_layer)(net_layer *layer);
|
||||||
|
|
||||||
|
status_t (*add_layer_attribut)(net_layer *layer, const char *name, int type, ...);
|
||||||
|
status_t (*remove_layer_attribut)(net_layer *layer, const char *name);
|
||||||
|
status_t (*find_layer_attribut)(net_layer *layer, const char *name,
|
||||||
|
int *type, void **attribut, size_t *size);
|
||||||
|
|
||||||
status_t (*push_buffer_up)(net_layer *me, net_buffer *buffer);
|
status_t (*push_buffer_up)(net_layer *me, net_buffer *buffer);
|
||||||
status_t (*push_buffer_down)(net_layer *me, net_buffer *buffer);
|
status_t (*push_buffer_down)(net_layer *me, net_buffer *buffer);
|
||||||
|
|
||||||
@@ -77,6 +114,11 @@ struct net_stack_module_info {
|
|||||||
uint32 (*read_buffer)(net_buffer *buffer, uint32 offset, void *data, uint32 bytes);
|
uint32 (*read_buffer)(net_buffer *buffer, uint32 offset, void *data, uint32 bytes);
|
||||||
uint32 (*write_buffer)(net_buffer *buffer, uint32 offset, const void *data, uint32 bytes);
|
uint32 (*write_buffer)(net_buffer *buffer, uint32 offset, const void *data, uint32 bytes);
|
||||||
|
|
||||||
|
status_t (*add_buffer_attribut)(net_buffer *buffer, const char *name, int type, ...);
|
||||||
|
status_t (*remove_buffer_attribut)(net_buffer *buffer, const char *name);
|
||||||
|
status_t (*find_buffer_attribut)(net_buffer *buffer, const char *name,
|
||||||
|
int *type, void **attribut, size_t *size);
|
||||||
|
|
||||||
void (*dump_buffer)(net_buffer *buffer);
|
void (*dump_buffer)(net_buffer *buffer);
|
||||||
|
|
||||||
// Buffer queues support
|
// Buffer queues support
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ status_t delete_buffer(net_buffer *buffer, bool interrupt_safe)
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
if (! g_buffers_pool)
|
if (! g_buffers_pool)
|
||||||
// Uh? From where come this net_data!?!
|
// Uh? From where come this net_buffer!?!
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
printf("delete_buffer(%p)\n", buffer);
|
printf("delete_buffer(%p)\n", buffer);
|
||||||
@@ -355,135 +355,69 @@ error1:
|
|||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
status_t remove_from_buffer(net_buffer *buffer, uint32 offset, uint32 bytes)
|
status_t remove_from_buffer(net_buffer *buffer, uint32 offset, uint32 bytes)
|
||||||
{
|
{
|
||||||
#if 0
|
net_buffer_chunk *first_chunk;
|
||||||
// TODO!!!
|
net_buffer_chunk *last_chunk;
|
||||||
|
net_buffer_chunk *previous_chunk;
|
||||||
|
uint32 offset_in_first_chunk;
|
||||||
|
uint32 offset_in_last_chunk;
|
||||||
|
|
||||||
net_buffer_chunk * ndn;
|
if (! buffer)
|
||||||
net_buffer_chunk * start_node;
|
return B_BAD_VALUE;
|
||||||
net_buffer_chunk * end_node;
|
|
||||||
uint32 start_node_offset;
|
if (offset >= buffer->len)
|
||||||
uint32 end_node_offset;
|
return B_BAD_VALUE;
|
||||||
net_buffer_chunk * start_split_node;
|
|
||||||
net_buffer_chunk * end_split_node;
|
|
||||||
uint8 * data;
|
|
||||||
|
|
||||||
if (bytes < 1)
|
if (bytes < 1)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
/*
|
first_chunk = find_buffer_chunk(buffer, offset, &offset_in_first_chunk, &previous_chunk);
|
||||||
Possibles cases:
|
if (! first_chunk)
|
||||||
[XXXXXXX|++++++].... Triming at start of node (start and/or end nodes)
|
|
||||||
[+++|XXXXXX|+++].... Triming in the middle of *one* node
|
|
||||||
[+++++|XXXXXXXX].... Triming at the end of start node
|
|
||||||
...[XXXXXXXXXXXXXX].... Triming one or more full node
|
|
||||||
*/
|
|
||||||
|
|
||||||
start_node = find_buffer_chunk(nd, offset, &start_node_offset, NULL);
|
|
||||||
if (! start_node)
|
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
end_node = find_buffer_chunk(nd, offset + bytes, &end_node_offset, NULL);
|
last_chunk = find_buffer_chunk(buffer, offset + bytes, &offset_in_last_chunk, NULL);
|
||||||
if (! end_node)
|
if (! last_chunk)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
if ( (start_node == end_node) &&
|
if (offset_in_last_chunk) {
|
||||||
(start_node_offset > 0) && (end_node_offset != end_node->len) )
|
// we must split last_chunk data in two parts,
|
||||||
// need to split one node into two parts, left & right, to be able to
|
// removing beginnin chunk from data lists and adding the ending one :-(
|
||||||
// trim data in the middle:
|
|
||||||
// [++++|XXXXXX|+++++++]
|
net_buffer_chunk *split_chunk;
|
||||||
return B_OK;
|
uint8 *split;
|
||||||
|
|
||||||
|
// remove the beginning of last_chunk data
|
||||||
|
|
||||||
|
split = (uint8 *) last_chunk->data;
|
||||||
|
split += offset_in_last_chunk;
|
||||||
|
split_chunk = new_buffer_chunk(split, last_chunk->len - offset_in_last_chunk);
|
||||||
|
// if (! split_chunk)
|
||||||
|
// goto error1;
|
||||||
|
// as split_chunk data comes from 'last_chunk', we don't
|
||||||
|
// ask to free this chunk data, as it would be by previous_chunk
|
||||||
|
split_chunk->free_func = NULL;
|
||||||
|
split_chunk->next_data = last_chunk->next_data;
|
||||||
|
|
||||||
|
// add the split_chunk to buffer's all_chunks list
|
||||||
|
split_chunk->next = buffer->all_chunks;
|
||||||
|
buffer->all_chunks = split_chunk;
|
||||||
|
|
||||||
|
last_chunk = split_chunk;
|
||||||
};
|
};
|
||||||
|
|
||||||
// if the trimmed part is in one node, we know now that it's:
|
if (offset_in_first_chunk) {
|
||||||
// |++++++|XXXXXXXXXXXX|, or:
|
// remove the end of first_chunk data: just forgot about last bytes of data :-)
|
||||||
// |XXXXXXXXX|+++++++++|
|
first_chunk->len = offset_in_first_chunk;
|
||||||
|
} else
|
||||||
|
first_chunk = previous_chunk;
|
||||||
|
|
||||||
if (start_node_offset)
|
// fix the data chunks list to remove chunk(s), if any
|
||||||
start_node->len = start_node_offset;
|
if (first_chunk)
|
||||||
|
first_chunk->next_data = last_chunk;
|
||||||
if (end_node_offset) {
|
else
|
||||||
data = (uint8 *) end_node->data;
|
buffer->data_chunks = last_chunk;
|
||||||
data += end_node_offset;
|
|
||||||
end_node->data = data;
|
|
||||||
end_node->len -= end_node_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
// start node must be split
|
|
||||||
split = (uint8 *) start_node->data;
|
|
||||||
split += start_node_offset;
|
|
||||||
start_split_node = new_buffer_chunk(split, start_node->len - start_node_offset);
|
|
||||||
if (! start_split_node)
|
|
||||||
goto error1;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (end_node_offset) {
|
|
||||||
// end node must be split
|
|
||||||
split = (uint8 *) end_node->data;
|
|
||||||
split += end_node_offset;
|
|
||||||
end_split_node = new_buffer_chunk(split, end_node->len - end_node_offset);
|
|
||||||
if (! end_split_node)
|
|
||||||
goto error2;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (start_split_node) {
|
|
||||||
};
|
|
||||||
|
|
||||||
ndn = start_node->next_data;
|
|
||||||
while (ndn->next_data != end_node) {
|
|
||||||
if (ndn->next_data == end_node)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ndn = ndn->next_data;
|
|
||||||
};
|
|
||||||
!= end_node
|
|
||||||
|
|
||||||
if (end_split_node) {
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// split start_node data chunk in two parts
|
|
||||||
start_node->len = start_node_offset;
|
|
||||||
|
|
||||||
start_split_node->free_func = NULL;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ndn->len = offset_in_node;
|
|
||||||
|
|
||||||
split_node->free_func = NULL; // as split_node data comes from 'ndn', we don't
|
|
||||||
// free this node data but only 'ndn' one...
|
|
||||||
|
|
||||||
// create a new node to host inserted data
|
|
||||||
new_node = new_buffer_chunk(data, bytes);
|
|
||||||
if (! new_node)
|
|
||||||
goto error2;
|
|
||||||
|
|
||||||
new_node->free_func = freethis; // can be NULL = don't free this chunk
|
|
||||||
new_node->free_cookie = NULL;
|
|
||||||
|
|
||||||
// add these nodes to node_list (nodes order don't matter in this list, so we do it the easy way :-)
|
|
||||||
split_node->next = nd->node_list;
|
|
||||||
new_node->next = split_node;
|
|
||||||
nd->node_list = new_node;
|
|
||||||
|
|
||||||
// Insert this new_node this node to the end of data_list
|
|
||||||
split_node->next_data = ndn->next_data;
|
|
||||||
ndn->next_data = new_node;
|
|
||||||
new_node->next_data = split_node;
|
|
||||||
|
|
||||||
nd->len -= bytes;
|
|
||||||
|
|
||||||
|
buffer->len -= bytes;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
error2:
|
|
||||||
g_memory_pool->delete_pool_node(g_buffer_chunks_pool, end_split_node);
|
|
||||||
error1:
|
|
||||||
if (start_split_node)
|
|
||||||
g_memory_pool->delete_pool_node(g_buffer_chunks_pool, start_split_node);
|
|
||||||
#endif
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -559,6 +493,27 @@ uint32 write_buffer(net_buffer *buffer, uint32 offset, const void *data, uint32
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
status_t add_buffer_attribut(net_buffer *buffer, const char *name, int type, ...)
|
||||||
|
{
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
status_t remove_buffer_attribut(net_buffer *buffer, const char *name)
|
||||||
|
{
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t find_buffer_attribut(net_buffer *buffer, const char *name, int *type, void **attribut, size_t *size)
|
||||||
|
{
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark [data(s) queues functions]
|
// #pragma mark [data(s) queues functions]
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
@@ -871,7 +826,7 @@ void dump_memory
|
|||||||
for ( j = i; j < i+16 ; j++ )
|
for ( j = i; j < i+16 ; j++ )
|
||||||
{
|
{
|
||||||
if ( j < len )
|
if ( j < len )
|
||||||
sprintf(ptr, "%02x ",byte[j]);
|
sprintf(ptr, "%02x ", byte[j]);
|
||||||
else
|
else
|
||||||
sprintf(ptr, " ");
|
sprintf(ptr, " ");
|
||||||
ptr += 3;
|
ptr += 3;
|
||||||
|
|||||||
@@ -32,6 +32,10 @@ extern status_t attach_buffer_free_element(net_buffer *buffer, void *arg1, voi
|
|||||||
extern uint32 read_buffer(net_buffer *buffer, uint32 offset, void *data, uint32 bytes);
|
extern uint32 read_buffer(net_buffer *buffer, uint32 offset, void *data, uint32 bytes);
|
||||||
extern uint32 write_buffer(net_buffer *buffer, uint32 offset, const void *data, uint32 bytes);
|
extern uint32 write_buffer(net_buffer *buffer, uint32 offset, const void *data, uint32 bytes);
|
||||||
|
|
||||||
|
extern status_t add_buffer_attribut(net_buffer *buffer, const char *name, int type, ...);
|
||||||
|
extern status_t remove_buffer_attribut(net_buffer *buffer, const char *name);
|
||||||
|
extern status_t find_buffer_attribut(net_buffer *buffer, const char *name, int *type, void **attribut, size_t *size);
|
||||||
|
|
||||||
extern void dump_buffer(net_buffer *buffer);
|
extern void dump_buffer(net_buffer *buffer);
|
||||||
|
|
||||||
// Network buffer(s) queue(s)
|
// Network buffer(s) queue(s)
|
||||||
|
|||||||
@@ -4,23 +4,32 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
|
#include <module.h>
|
||||||
|
|
||||||
|
#include "memory_pool.h"
|
||||||
#include "layers_manager.h"
|
#include "layers_manager.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
|
||||||
/* Defines we need */
|
|
||||||
#define NET_LAYER_MODULES_ROOT "network/layers/"
|
|
||||||
|
|
||||||
struct layers_list {
|
struct layers_list {
|
||||||
net_layer *first;
|
struct net_layer *first;
|
||||||
sem_id lock;
|
sem_id lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct layers_list g_layers;
|
static struct layers_list g_layers;
|
||||||
|
|
||||||
|
static memory_pool * g_layers_pool = NULL;
|
||||||
|
#define LAYERS_PER_POOL (64)
|
||||||
|
|
||||||
|
static net_layer * new_layer(const char *name, net_layer_module_info *module, void *cookie);
|
||||||
|
static status_t delete_layer(net_layer *layer);
|
||||||
|
|
||||||
|
extern struct memory_pool_module_info *g_memory_pool;
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark [Start/Stop functions]
|
// #pragma mark [Start/Stop functions]
|
||||||
|
|
||||||
|
|
||||||
@@ -54,13 +63,12 @@ status_t start_layers_manager()
|
|||||||
if (!strlen(module_name))
|
if (!strlen(module_name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
printf("layers_manager: loading %s layer(s) module\n", module_name);
|
||||||
if (get_module(module_name, (module_info **) &nlmi) != B_OK)
|
if (get_module(module_name, (module_info **) &nlmi) != B_OK)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
printf("layers_manager: initing %s layer(s) module...\n", module_name);
|
|
||||||
// allow this module to register one or more interfaces
|
|
||||||
nlmi->init(NULL);
|
|
||||||
// this module may have been acquire more time by calling register_layer()
|
// this module may have been acquire more time by calling register_layer()
|
||||||
|
// or have B_KEEP_LOADED flag, so we don't care...
|
||||||
put_module(module_name);
|
put_module(module_name);
|
||||||
};
|
};
|
||||||
close_module_list(module_list);
|
close_module_list(module_list);
|
||||||
@@ -70,6 +78,7 @@ status_t start_layers_manager()
|
|||||||
acquire_sem(g_layers.lock);
|
acquire_sem(g_layers.lock);
|
||||||
layer = g_layers.first;
|
layer = g_layers.first;
|
||||||
while (layer) {
|
while (layer) {
|
||||||
|
layer->module->init(layer);
|
||||||
layer->module->enable(layer, true);
|
layer->module->enable(layer, true);
|
||||||
layer = layer->next;
|
layer = layer->next;
|
||||||
};
|
};
|
||||||
@@ -90,7 +99,7 @@ status_t stop_layers_manager()
|
|||||||
|
|
||||||
// TODO: handle multiple layers registered by same net module
|
// TODO: handle multiple layers registered by same net module
|
||||||
|
|
||||||
// unregister all layers...
|
// disable all layers...
|
||||||
layer = g_layers.first;
|
layer = g_layers.first;
|
||||||
while (layer) {
|
while (layer) {
|
||||||
next = layer->next;
|
next = layer->next;
|
||||||
@@ -99,8 +108,12 @@ status_t stop_layers_manager()
|
|||||||
// down the layer if currently up
|
// down the layer if currently up
|
||||||
layer->module->enable(layer, false);
|
layer->module->enable(layer, false);
|
||||||
layer->module->uninit(layer);
|
layer->module->uninit(layer);
|
||||||
|
|
||||||
|
delete_layer(layer);
|
||||||
|
|
||||||
printf("layers_manager: unloading %s layer(s) module\n", module_name);
|
printf("layers_manager: unloading %s layer(s) module\n", module_name);
|
||||||
put_module(module_name);
|
put_module(module_name);
|
||||||
|
|
||||||
layer = next;
|
layer = next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -114,39 +127,49 @@ status_t stop_layers_manager()
|
|||||||
// #pragma mark [Public functions]
|
// #pragma mark [Public functions]
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
status_t register_layer(net_layer *layer)
|
status_t register_layer(const char *name, net_layer_module_info *module, void *cookie, net_layer **_layer)
|
||||||
{
|
{
|
||||||
status_t status;
|
status_t status;
|
||||||
module_info *dummy;
|
module_info *dummy;
|
||||||
|
net_layer *layer;
|
||||||
|
|
||||||
|
if (name == NULL ||
|
||||||
|
strlen(name) <= 0 ||
|
||||||
|
module == NULL)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
layer = new_layer(name, module, cookie);
|
||||||
if (!layer)
|
if (!layer)
|
||||||
return B_ERROR;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
if (layer->module == NULL)
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
// acquire this module, to keep it loaded while this layer is registered
|
// acquire this module, to keep it loaded while this layer is registered
|
||||||
status = get_module(layer->module->info.name, &dummy);
|
status = get_module(module->info.name, &dummy);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
goto error1;
|
||||||
|
|
||||||
layer->layers_above = NULL;
|
|
||||||
layer->layers_below = NULL;
|
|
||||||
|
|
||||||
status = acquire_sem(g_layers.lock);
|
status = acquire_sem(g_layers.lock);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
goto error2;
|
||||||
|
|
||||||
layer->next = g_layers.first;
|
layer->next = g_layers.first;
|
||||||
g_layers.first = layer;
|
g_layers.first = layer;
|
||||||
|
|
||||||
release_sem(g_layers.lock);
|
release_sem(g_layers.lock);
|
||||||
|
|
||||||
|
|
||||||
printf("layers_manager: '%s' layer registered\n", layer->name);
|
printf("layers_manager: '%s' layer registered\n", layer->name);
|
||||||
|
|
||||||
|
if (_layer)
|
||||||
|
*_layer = layer;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
|
error2:
|
||||||
|
put_module(module->info.name);
|
||||||
|
error1:
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
status_t unregister_layer(net_layer *layer)
|
status_t unregister_layer(net_layer *layer)
|
||||||
{
|
{
|
||||||
@@ -166,15 +189,57 @@ status_t unregister_layer(net_layer *layer)
|
|||||||
while (p && p->next != layer)
|
while (p && p->next != layer)
|
||||||
p = p->next;
|
p = p->next;
|
||||||
|
|
||||||
if (!p)
|
if (!p) {
|
||||||
|
// Oh oh... :-(
|
||||||
printf("layers_manager: unregister_layer(): %p layer not found in list!\n", layer);
|
printf("layers_manager: unregister_layer(): %p layer not found in list!\n", layer);
|
||||||
else
|
release_sem(g_layers.lock);
|
||||||
p->next = layer->next;
|
return B_ERROR;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
p->next = layer->next;
|
||||||
|
};
|
||||||
release_sem(g_layers.lock);
|
release_sem(g_layers.lock);
|
||||||
|
|
||||||
|
layer->module->uninit(layer);
|
||||||
|
|
||||||
printf("layers_manager: '%s' layer unregistered\n", layer->name);
|
printf("layers_manager: '%s' layer unregistered\n", layer->name);
|
||||||
|
|
||||||
|
put_module(layer->module->info.name);
|
||||||
|
|
||||||
|
return delete_layer(layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
status_t add_layer_attribut(net_layer *layer, const char *name, int type, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, type);
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case NET_ATTRIBUT_POINTER:
|
||||||
|
// hack
|
||||||
|
layer->cookie = va_arg(args, void *);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
status_t remove_layer_attribut(net_layer *layer, const char *name)
|
||||||
|
{
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t find_layer_attribut(net_layer *layer, const char *name, int *type, void **attribut, size_t *size)
|
||||||
|
{
|
||||||
|
*attribut = &layer->cookie;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,6 +276,7 @@ status_t push_buffer_up(net_layer *layer, net_buffer *buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
status_t push_buffer_down(net_layer *layer, net_buffer *buffer)
|
status_t push_buffer_down(net_layer *layer, net_buffer *buffer)
|
||||||
{
|
{
|
||||||
net_layer *below;
|
net_layer *below;
|
||||||
@@ -244,27 +310,50 @@ status_t push_buffer_down(net_layer *layer, net_buffer *buffer)
|
|||||||
// #pragma mark [Private functions]
|
// #pragma mark [Private functions]
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
// --------------------------------------------------
|
||||||
// ----------------------------------------------------
|
static net_layer * new_layer(const char *name, net_layer_module_info *module, void *cookie)
|
||||||
status_t interface_reader(void *args)
|
|
||||||
{
|
{
|
||||||
ifnet_t *iface = args;
|
net_layer *layer;
|
||||||
net_buffer *buffer;
|
|
||||||
status_t status;
|
|
||||||
|
|
||||||
if (!iface || iface->module == NULL)
|
if (! g_layers_pool)
|
||||||
|
g_layers_pool = g_memory_pool->new_pool(sizeof(*layer), LAYERS_PER_POOL);
|
||||||
|
|
||||||
|
if (! g_layers_pool)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
layer = (net_layer *) g_memory_pool->new_pool_node(g_layers_pool);
|
||||||
|
if (! layer)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
layer->name = strdup(name);
|
||||||
|
layer->module = module;
|
||||||
|
layer->cookie = cookie;
|
||||||
|
|
||||||
|
layer->layers_above = NULL;
|
||||||
|
layer->layers_below = NULL;
|
||||||
|
|
||||||
|
return layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
static status_t delete_layer(net_layer *layer)
|
||||||
|
{
|
||||||
|
if (!layer)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
while(iface->if_flags & IFF_UP) {
|
if (! g_layers_pool)
|
||||||
buffer = NULL;
|
// Uh? From where come this net_data!?!
|
||||||
status = iface->module->receive_buffer(iface, &buffer);
|
return B_ERROR;
|
||||||
if (status < B_OK || buffer == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
dump_buffer(buffer);
|
if (layer->name)
|
||||||
delete_buffer(buffer, false);
|
free(layer->name);
|
||||||
};
|
if (layer->layers_above)
|
||||||
|
free(layer->layers_above);
|
||||||
|
if (layer->layers_below)
|
||||||
|
free(layer->layers_below);
|
||||||
|
|
||||||
return B_OK;
|
return g_memory_pool->delete_pool_node(g_layers_pool, layer);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#ifndef OBOS_NET_STACK_LAYERS_MANAGER_H
|
#ifndef OBOS_NET_STACK_LAYERS_MANAGER_H
|
||||||
#define OBOS_NET_STACK_LAYERS_MANAGER_H
|
#define OBOS_NET_STACK_LAYERS_MANAGER_H
|
||||||
|
|
||||||
#include "net_layer.h"
|
#include "net_stack.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -14,9 +14,15 @@ extern "C" {
|
|||||||
extern status_t start_layers_manager();
|
extern status_t start_layers_manager();
|
||||||
extern status_t stop_layers_manager();
|
extern status_t stop_layers_manager();
|
||||||
|
|
||||||
extern status_t register_layer(net_layer *layer);
|
extern status_t register_layer(const char *name, net_layer_module_info *module, void *cookie,
|
||||||
|
net_layer **me);
|
||||||
extern status_t unregister_layer(net_layer *layer);
|
extern status_t unregister_layer(net_layer *layer);
|
||||||
|
|
||||||
|
extern status_t add_layer_attribut(net_layer *layer, const char *name, int type, ...);
|
||||||
|
extern status_t remove_layer_attribut(net_layer *layer, const char *name);
|
||||||
|
extern status_t find_layer_attribut(net_layer *layer, const char *name,
|
||||||
|
int *type, void **attribut, size_t *size);
|
||||||
|
|
||||||
extern status_t push_buffer_up(net_layer *me, struct net_buffer *buffer);
|
extern status_t push_buffer_up(net_layer *me, struct net_buffer *buffer);
|
||||||
extern status_t push_buffer_down(net_layer *me, struct net_buffer *buffer);
|
extern status_t push_buffer_down(net_layer *me, struct net_buffer *buffer);
|
||||||
|
|
||||||
|
|||||||
@@ -73,6 +73,9 @@ struct net_stack_module_info nsmi = {
|
|||||||
// Layers handling
|
// Layers handling
|
||||||
register_layer,
|
register_layer,
|
||||||
unregister_layer,
|
unregister_layer,
|
||||||
|
add_layer_attribut,
|
||||||
|
remove_layer_attribut,
|
||||||
|
find_layer_attribut,
|
||||||
|
|
||||||
push_buffer_up,
|
push_buffer_up,
|
||||||
push_buffer_down,
|
push_buffer_down,
|
||||||
@@ -92,6 +95,10 @@ struct net_stack_module_info nsmi = {
|
|||||||
read_buffer,
|
read_buffer,
|
||||||
write_buffer,
|
write_buffer,
|
||||||
|
|
||||||
|
add_buffer_attribut,
|
||||||
|
remove_buffer_attribut,
|
||||||
|
find_buffer_attribut,
|
||||||
|
|
||||||
dump_buffer,
|
dump_buffer,
|
||||||
|
|
||||||
// net_buffer_queue support
|
// net_buffer_queue support
|
||||||
|
|||||||
Reference in New Issue
Block a user