Attributes support evolution. Now layers support attributes too.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6419 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Philippe Houdoin 2004-01-29 23:04:38 +00:00
parent 4d61634cbe
commit 313aa5fc08
14 changed files with 245 additions and 137 deletions

View File

@ -40,10 +40,10 @@ struct net_layer_module_info nlmi;
static struct net_stack_module_info *g_stack = NULL;
net_attribute_id ethernet_header_attr;
net_attribute_id ethernet_from_attr;
net_attribute_id ethernet_to_attr;
net_attribute_id ethernet_protocol_attr;
string_token ethernet_header_attr;
string_token ethernet_from_attr;
string_token ethernet_to_attr;
string_token ethernet_protocol_attr;
static void dump_ethernet(net_buffer *buffer)
@ -105,7 +105,7 @@ static status_t process_input(net_layer *me, net_buffer *buffer)
// strip ethernet header
g_stack->remove_from_buffer(buffer, 0, 14);
return g_stack->send_up(me, buffer);
return g_stack->send_layers_up(me, buffer);
}

View File

@ -16,6 +16,23 @@ extern "C" {
// String tokens use here and there by stack components
typedef const void *string_token;
// Networking attribute(s) definition
typedef struct net_attribute net_attribute;
#define NET_ATTRIBUTE_TYPE_MASK 0xFF // Up to 256 basic types
#define NET_ATTRIBUTE_FLAGS_MASK 0xFFFFFF00
enum {
NET_ATTRIBUTE_BOOL = 1, // ... = bool value
NET_ATTRIBUTE_BYTE, // ... = uint8 value
NET_ATTRIBUTE_INT16, // ... = uint16 value
NET_ATTRIBUTE_INT32, // ... = uint32 value
NET_ATTRIBUTE_INT64, // ... = uint64 value
NET_ATTRIBUTE_DATA, // ... = void *data, size_t data_len
NET_ATTRIBUTE_STRING, // ... = char *string
NET_ATTRIBUTE_POINTER, // ... = void *ptr
NET_ATTRIBUTE_IOVEC // ... = int nb, iovec *vec
};
// Networking buffer(s) definition
typedef struct net_buffer net_buffer;
typedef struct net_buffer_queue net_buffer_queue;
@ -63,25 +80,9 @@ struct net_layer {
uint32 use_count;
struct net_layer **layers_above;
struct net_layer **layers_below;
struct net_attribute *attributes; // layer attributes
};
typedef string_token net_attribute_id;
#define NET_ATTRIBUTE_TYPE_MASK 0xFF // Up to 256 basic types
#define NET_ATTRIBUTE_FLAGS_MASK 0xFFFFFF00
enum {
NET_ATTRIBUTE_BOOL,
NET_ATTRIBUTE_BYTE,
NET_ATTRIBUTE_INT16,
NET_ATTRIBUTE_INT32,
NET_ATTRIBUTE_INT64,
NET_ATTRIBUTE_DATA,
NET_ATTRIBUTE_STRING,
NET_ATTRIBUTE_POINTER,
NET_ATTRIBUTE_IOVEC
};
// Network stack main module definition
struct net_stack_module_info {
@ -108,13 +109,13 @@ struct net_stack_module_info {
status_t (*unregister_layer)(net_layer *layer);
net_layer * (*find_layer)(const char *name);
status_t (*add_layer_attribute)(net_layer *layer, net_attribute_id id, int type, ...);
status_t (*remove_layer_attribute)(net_layer *layer, net_attribute_id id);
status_t (*find_layer_attribute)(net_layer *layer, net_attribute_id id,
status_t (*add_layer_attribute)(net_layer *layer, string_token id, int type, ...);
status_t (*remove_layer_attribute)(net_layer *layer, string_token id, int index);
status_t (*find_layer_attribute)(net_layer *layer, string_token id, int index,
int *type, void **value, size_t *size);
status_t (*send_up)(net_layer *me, net_buffer *buffer);
status_t (*send_down)(net_layer *me, net_buffer *buffer);
status_t (*send_layers_up)(net_layer *me, net_buffer *buffer);
status_t (*send_layers_down)(net_layer *me, net_buffer *buffer);
/*
* Buffer(s) support
@ -132,20 +133,20 @@ struct net_stack_module_info {
// specials offsets for add_to_buffer()
#define BUFFER_BEGIN 0
#define BUFFER_END 0xFFFFFFFF
status_t (*add_to_buffer)(net_buffer *buffer, uint32 offset, const void *data, uint32 bytes, buffer_chunk_free_func freethis);
status_t (*remove_from_buffer)(net_buffer *buffer, uint32 offset, uint32 bytes);
status_t (*add_to_buffer)(net_buffer *buffer, uint32 offset, const void *data, size_t bytes, buffer_chunk_free_func freethis);
status_t (*remove_from_buffer)(net_buffer *buffer, uint32 offset, size_t bytes);
status_t (*attach_buffer_free_element)(net_buffer *buffer, void *arg1, void *arg2, buffer_chunk_free_func freethis);
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);
size_t (*read_buffer)(net_buffer *buffer, uint32 offset, void *data, size_t bytes);
size_t (*write_buffer)(net_buffer *buffer, uint32 offset, const void *data, size_t bytes);
// Flags to combine with
#define FROM_BUFFER 0x010000
#define FROM_BUFFER 0x010000 // ... = int offset, int size
#define NETWORK_ORDER 0x020000
status_t (*add_buffer_attribute)(net_buffer *buffer, net_attribute_id id, int type, ...);
status_t (*remove_buffer_attribute)(net_buffer *buffer, net_attribute_id id);
status_t (*find_buffer_attribute)(net_buffer *buffer, net_attribute_id id,
status_t (*add_buffer_attribute)(net_buffer *buffer, string_token id, int type, ...);
status_t (*remove_buffer_attribute)(net_buffer *buffer, string_token id, int index);
status_t (*find_buffer_attribute)(net_buffer *buffer, string_token id, int index,
int *type, void **value, size_t *size);
void (*dump_buffer)(net_buffer *buffer);
@ -169,7 +170,7 @@ struct net_stack_module_info {
// Lockers
// Misc.
void (*dump_memory)(const char *prefix, const void *data, uint32 len);
void (*dump_memory)(const char *prefix, const void *data, size_t len);
// Memory Pools support
memory_pool * (*new_pool)(size_t node_size, uint32 node_count);

View File

@ -275,7 +275,7 @@ status_t device_reader(void *args)
g_stack->add_to_buffer(buffer, 0, frame, sz, (buffer_chunk_free_func) free);
dprintf("%s: input packet %p:\n", me->name, buffer);
if (g_stack->send_up(me, buffer) != B_OK) {
if (g_stack->send_layers_up(me, buffer) != B_OK) {
// nobody above us *eat* this packet, so we drop it ourself :-(
dprintf("%s: okay, nobody cares about this input packet %p: deletion!\n", me->name, buffer);
g_stack->dump_buffer(buffer);

View File

@ -43,7 +43,7 @@ static status_t process_output(net_layer *me, net_buffer *buffer)
return B_ERROR;
// Here the magical loopback effect ;-)
return g_stack->send_up(me, buffer);
return g_stack->send_layers_up(me, buffer);
}
// #pragma mark -

View File

@ -16,7 +16,7 @@ struct net_layer_module_info nlmi;
static struct net_stack_module_info *g_stack = NULL;
net_attribute_id ethernet_protocol_attr;
string_token ethernet_protocol_attr;
typedef struct ethernet_addr {
uint8 byte[6];
@ -134,7 +134,7 @@ static status_t process_input(net_layer *me, net_buffer *buffer)
if (!buffer)
return B_ERROR;
if (g_stack->find_buffer_attribute(buffer, ethernet_protocol_attr, NULL, (void **) &protocol, NULL) != B_OK)
if (g_stack->find_buffer_attribute(buffer, ethernet_protocol_attr, 0, NULL, (void **) &protocol, NULL) != B_OK)
return B_ERROR;
if (*protocol != htons(0x0806)) // ARP on Ethernet protocol value

View File

@ -16,7 +16,7 @@
typedef struct ipv4_addr {
uint8 byte[4];
} ipv4_addr;
} _PACKED ipv4_addr;
typedef struct ipv4_header {
@ -43,7 +43,7 @@ status_t std_ops(int32 op, ...);
struct net_layer_module_info nlmi;
static struct net_stack_module_info *g_stack = NULL;
net_attribute_id ethernet_protocol_attr;
string_token ethernet_protocol_attr;
static uint32 g_next_ipv4_id = 0;
static void dump_ipv4_header(net_buffer *buffer)
@ -109,7 +109,7 @@ static status_t process_input(net_layer *me, net_buffer *buffer)
if (!buffer)
return B_ERROR;
if (g_stack->find_buffer_attribute(buffer, ethernet_protocol_attr, NULL, (void **) &protocol, NULL) != B_OK)
if (g_stack->find_buffer_attribute(buffer, ethernet_protocol_attr, 0, NULL, (void **) &protocol, NULL) != B_OK)
return B_ERROR;
if (*protocol != htons(0x0800)) // IPv4 on Ethernet protocol value

View File

@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
#include <iovec.h>
#include <stdarg.h>
#include <KernelExport.h>
#include <OS.h>
@ -17,14 +18,80 @@
static memory_pool *g_attributes_pool = NULL;
extern memory_pool_module_info *g_memory_pool;
// Privates prototypes
// -------------------
// LET'S GO FOR IMPLEMENTATION
// ------------------------------------
net_attribute * new_attribute(net_attribute **in_list, const void *id)
status_t add_attribute(net_attribute **in_list, string_token id, int type, va_list args)
{
net_attribute *attr;
attr = new_attribute(in_list, id);
if (! attr)
return B_NO_MEMORY;
attr->type = type;
switch(type & NET_ATTRIBUTE_TYPE_MASK) {
case NET_ATTRIBUTE_BOOL:
attr->u.boolean = va_arg(args, bool);
break;
case NET_ATTRIBUTE_BYTE:
attr->u.byte = va_arg(args, uint8);
break;
case NET_ATTRIBUTE_INT16:
attr->u.word = va_arg(args, uint16);
break;
case NET_ATTRIBUTE_INT32:
attr->u.dword = va_arg(args, uint32);
break;
case NET_ATTRIBUTE_INT64:
attr->u.ddword = va_arg(args, uint64);
break;
case NET_ATTRIBUTE_DATA:
{ // void *data, size_t data_len
void *data = va_arg(args, void *);
size_t sz = va_arg(args, size_t);
if (sz > MAX_ATTRIBUTE_DATA_LEN)
sz = MAX_ATTRIBUTE_DATA_LEN;
memcpy(attr->u.data, data, sz);
break;
}
case NET_ATTRIBUTE_STRING:
strncpy(attr->u.data, va_arg(args, char *), MAX_ATTRIBUTE_DATA_LEN);
break;
case NET_ATTRIBUTE_POINTER:
// NB: data behind pointer ARE NOT copied
attr->u.ptr = va_arg(args, void *);
break;
case NET_ATTRIBUTE_IOVEC:
{ // int nb, iovec *vec
int nb = va_arg(args, int);
iovec * vec = va_arg(args, iovec *);
if (nb > MAX_ATTRIBUTE_IOVECS)
nb = MAX_ATTRIBUTE_IOVECS;
memcpy(&attr->u.vec, vec, nb * sizeof(iovec));
break;
}
}
return B_OK;
}
net_attribute * new_attribute(net_attribute **in_list, string_token id)
{
net_attribute *attr;
@ -84,8 +151,8 @@ status_t delete_attribute(net_attribute *attr, net_attribute **from_list)
}
net_attribute * find_attribute(net_attribute *list, const void *id, int *type,
void **value, size_t *size)
net_attribute * find_attribute(net_attribute *list, string_token id, int index,
int *type, void **value, size_t *size)
{
net_attribute *attr;
@ -95,7 +162,7 @@ net_attribute * find_attribute(net_attribute *list, const void *id, int *type,
// dprintf("find_attribute(%p, %p)\n", list, id);
attr = list;
while (attr) {
if (attr->id == id) {
if (attr->id == id && index-- == 0) {
if (type) *type = attr->type;
if (size) *size = attr->size;
if (value) {

View File

@ -5,8 +5,10 @@
#ifndef OBOS_NET_STACK_ATTRIBUTE_H
#define OBOS_NET_STACK_ATTRIBUTE_H
#include <SupportDefs.h>
#include <iovec.h>
#include <stdarg.h>
#include <SupportDefs.h>
#include "net_stack.h"
@ -14,27 +16,30 @@
extern "C" {
#endif
typedef struct net_attribute {
#define MAX_ATTRIBUTE_IOVECS (16)
#define MAX_ATTRIBUTE_DATA_LEN (256)
struct net_attribute {
struct net_attribute *next;
string_token id;
uint32 type;
uint32 size;
size_t size;
union {
bool boolean;
uint8 byte;
uint16 word;
uint32 dword;
uint64 ddword;
char data[256];
char data[MAX_ATTRIBUTE_DATA_LEN]; // Beware: data max size is limited :-(
void *ptr;
iovec vec[16]; // Beware: 16 max :-(
iovec vec[MAX_ATTRIBUTE_IOVECS]; // Beware: these are limited too :-(
} u;
} net_attribute;
};
extern status_t add_attribute(net_attribute **in_list, string_token id, int type, va_list args);
extern net_attribute * new_attribute(net_attribute **in_list, string_token id);
extern status_t delete_attribute(net_attribute *attribut, net_attribute **from_list);
extern net_attribute * find_attribute(net_attribute *list, string_token id, int *type, void **value, size_t *size);
extern net_attribute * find_attribute(net_attribute *list, string_token id, int index, int *type, void **value, size_t *size);
#ifdef __cplusplus
}

View File

@ -18,7 +18,7 @@ typedef struct net_buffer_chunk {
struct net_buffer_chunk *next_data;
uint32 ref_count; // this data is referenced by 'ref_count' net_buffer_chunk(s)
const void *data; // address of data
uint32 len; // in bytes (could be 0, with *guest* add_buffer_free_element() node
size_t len; // in bytes (could be 0, with *guest* add_buffer_free_element() node
buffer_chunk_free_func free_func; // if NULL, don't free it!
void * free_cookie; // if != NULL, free_func(cookie, data) is called... otherwise, free_func(data)
} net_buffer_chunk;
@ -68,11 +68,11 @@ extern memory_pool_module_info *g_memory_pool;
// Privates prototypes
// -------------------
static net_buffer_chunk * new_buffer_chunk(const void *data, uint32 len);
static net_buffer_chunk * new_buffer_chunk(const void *data, size_t len);
static net_buffer_chunk * find_buffer_chunk(net_buffer *buffer, uint32 offset, uint32 *offset_in_chunk, net_buffer_chunk **previous_chunk);
static status_t prepend_buffer(net_buffer *buffer, const void *data, uint32 bytes, buffer_chunk_free_func freethis);
static status_t append_buffer(net_buffer *buffer, const void *data, uint32 bytes, buffer_chunk_free_func freethis);
static status_t prepend_buffer(net_buffer *buffer, const void *data, size_t bytes, buffer_chunk_free_func freethis);
static status_t append_buffer(net_buffer *buffer, const void *data, size_t bytes, buffer_chunk_free_func freethis);
static int32 buffers_purgatory_thread(void * data);
@ -84,9 +84,6 @@ static status_t buffer_queue_killer(memory_pool * pool, void * node, void *
// ------------------------------------
// #pragma mark [Start/Stop Service functions]
// --------------------------------------------------
status_t start_buffers_service()
{
@ -138,7 +135,7 @@ status_t stop_buffers_service()
}
// #pragma mark [Public functions]
// #pragma mark -
// --------------------------------------------------
@ -320,7 +317,7 @@ status_t attach_buffer_free_element(net_buffer *buffer, void *arg1, void *arg2,
// --------------------------------------------------
status_t add_to_buffer(net_buffer *buffer, uint32 offset, const void *data, uint32 bytes, buffer_chunk_free_func freethis)
status_t add_to_buffer(net_buffer *buffer, uint32 offset, const void *data, size_t bytes, buffer_chunk_free_func freethis)
{
net_buffer_chunk *previous_chunk;
net_buffer_chunk *next_chunk;
@ -405,7 +402,7 @@ error1:
// --------------------------------------------------
status_t remove_from_buffer(net_buffer *buffer, uint32 offset, uint32 bytes)
status_t remove_from_buffer(net_buffer *buffer, uint32 offset, size_t bytes)
{
net_buffer_chunk *first_chunk;
net_buffer_chunk *last_chunk;
@ -474,12 +471,12 @@ status_t remove_from_buffer(net_buffer *buffer, uint32 offset, uint32 bytes)
// --------------------------------------------------
uint32 read_buffer(net_buffer *buffer, uint32 offset, void *data, uint32 bytes)
size_t read_buffer(net_buffer *buffer, uint32 offset, void *data, size_t bytes)
{
net_buffer_chunk *chunk;
uint32 offset_in_chunk;
uint32 len;
uint32 chunk_len;
size_t len;
size_t chunk_len;
uint8 *from;
uint8 *to;
@ -509,12 +506,12 @@ 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)
size_t write_buffer(net_buffer *buffer, uint32 offset, const void *data, size_t bytes)
{
net_buffer_chunk *chunk;
uint32 offset_in_chunk;
uint32 len;
uint32 chunk_len;
size_t len;
size_t chunk_len;
uint8 *from;
uint8 *to;
@ -545,42 +542,39 @@ uint32 write_buffer(net_buffer *buffer, uint32 offset, const void *data, uint32
return len;
}
// #pragma mark -
// --------------------------------------------------
status_t add_buffer_attribute(net_buffer *buffer, const void *id, int type, ...)
status_t add_buffer_attribute(net_buffer *buffer, string_token id, int type, ...)
{
net_attribute *attr;
status_t status;
va_list args;
if (! buffer)
return B_BAD_VALUE;
attr = new_attribute(&buffer->attributes, id);
if (! attr)
return B_NO_MEMORY;
if (type & FROM_BUFFER) {
va_list args;
net_attribute *attr;
net_buffer_chunk *chunk;
uint32 offset;
uint32 offset_in_chunk;
uint32 size;
size_t size;
uint8 *ptr;
type = (type & NET_ATTRIBUTE_FLAGS_MASK);
va_start(args, type);
offset = va_arg(args, int);
size = va_arg(args, int);
offset = va_arg(args, uint32);
size = va_arg(args, size_t);
va_end(args);
chunk = find_buffer_chunk(buffer, offset, &offset_in_chunk, NULL);
if (chunk == NULL) {
delete_attribute(attr, &buffer->attributes);
if (chunk == NULL)
return B_BAD_VALUE;
};
attr = new_attribute(&buffer->attributes, id);
if (! attr)
return B_NO_MEMORY;
attr->size = size;
if (size < chunk->len - offset_in_chunk) {
ptr = (uint8 *) chunk->data;
ptr += offset_in_chunk;
@ -614,26 +608,30 @@ status_t add_buffer_attribute(net_buffer *buffer, const void *id, int type, ...)
};
attr->type = type | NET_ATTRIBUTE_IOVEC;
}
};
status = B_OK;
} else {
// Not implemented
return B_ERROR;
}
// default attribute types
va_start(args, type);
status = add_attribute(&buffer->attributes, id, type, args);
va_end(args);
};
return B_OK;
return status;
}
// --------------------------------------------------
status_t remove_buffer_attribute(net_buffer *buffer, const void *id)
status_t remove_buffer_attribute(net_buffer *buffer, string_token id, int index)
{
net_attribute *attr;
if (! buffer)
return B_BAD_VALUE;
attr = find_attribute(buffer->attributes, id, NULL, NULL, NULL);
attr = find_attribute(buffer->attributes, id, index, NULL, NULL, NULL);
if (! attr)
return B_NAME_NOT_FOUND;
@ -641,14 +639,14 @@ status_t remove_buffer_attribute(net_buffer *buffer, const void *id)
}
status_t find_buffer_attribute(net_buffer *buffer, const void *id, int *type, void **value, size_t *size)
status_t find_buffer_attribute(net_buffer *buffer, string_token id, int index, int *type, void **value, size_t *size)
{
net_attribute *attr;
if (! buffer)
return B_BAD_VALUE;
attr = find_attribute(buffer->attributes, id, type, value, size);
attr = find_attribute(buffer->attributes, id, index, type, value, size);
if (! attr)
return B_NAME_NOT_FOUND;
@ -656,7 +654,7 @@ status_t find_buffer_attribute(net_buffer *buffer, const void *id, int *type, vo
}
// #pragma mark [buffer(s) queues functions]
// #pragma mark -
// --------------------------------------------------
net_buffer_queue * new_buffer_queue(size_t max_bytes)
@ -807,7 +805,7 @@ size_t dequeue_buffer(net_buffer_queue *queue, net_buffer **buffer, bigtime_t t
}
// #pragma mark [Helper functions]
// #pragma mark -
// --------------------------------------------------
static net_buffer_chunk * new_buffer_chunk(const void *data, uint32 len)
@ -979,7 +977,7 @@ void dump_buffer(net_buffer *buffer)
}
// #pragma mark [Packets Purgatory functions]
// #pragma mark -
// --------------------------------------------------
static int32 buffers_purgatory_thread(void *data)

View File

@ -25,17 +25,17 @@ extern net_buffer * clone_buffer(net_buffer *from);
extern net_buffer * split_buffer(net_buffer *from, uint32 offset);
extern status_t merge_buffers(net_buffer *begin, net_buffer *end);
extern status_t add_to_buffer(net_buffer *buffer, uint32 offset, const void *data, uint32 bytes, buffer_chunk_free_func freethis);
extern status_t remove_from_buffer(net_buffer *buffer, uint32 offset, uint32 bytes);
extern status_t add_to_buffer(net_buffer *buffer, uint32 offset, const void *data, size_t bytes, buffer_chunk_free_func freethis);
extern status_t remove_from_buffer(net_buffer *buffer, uint32 offset, size_t bytes);
extern status_t attach_buffer_free_element(net_buffer *buffer, void *arg1, void *arg2, buffer_chunk_free_func freethis);
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 size_t read_buffer(net_buffer *buffer, uint32 offset, void *data, size_t bytes);
extern size_t write_buffer(net_buffer *buffer, uint32 offset, const void *data, size_t bytes);
extern status_t add_buffer_attribute(net_buffer *buffer, const void *id, int type, ...);
extern status_t remove_buffer_attribute(net_buffer *buffer, const void *id);
extern status_t find_buffer_attribute(net_buffer *buffer, const void *id, int *type, void **value, size_t *size);
extern status_t add_buffer_attribute(net_buffer *buffer, string_token id, int type, ...);
extern status_t remove_buffer_attribute(net_buffer *buffer, string_token id, int index);
extern status_t find_buffer_attribute(net_buffer *buffer, string_token id, int index, int *type, void **value, size_t *size);
extern void dump_buffer(net_buffer *buffer);

View File

@ -10,7 +10,7 @@ void dump_memory
(
const char * prefix,
const void * data,
uint32 len
size_t len
)
{
uint32 i,j;

View File

@ -1,6 +1,8 @@
#ifndef DUMP_H
#define DUMP_H
extern void dump_memory(const char *prefix, const void *data, uint32 len);
#include <SupportDefs.h>
extern void dump_memory(const char *prefix, const void *data, size_t len);
#endif

View File

@ -13,6 +13,7 @@
#include "memory_pool.h"
#include "layers_manager.h"
#include "buffer.h"
#include "attribute.h"
#include "stack.h" // for string_{to|for}_token()
struct layers_list {
@ -31,10 +32,8 @@ static status_t delete_layer(net_layer *layer);
extern memory_pool_module_info *g_memory_pool;
string_token g_joker_token = 0;
// #pragma mark [Start/Stop functions]
string_token g_joker_token = 0;
string_token g_layers_trace_attr = 0;
// --------------------------------------------------
status_t start_layers_manager(void)
@ -43,6 +42,7 @@ status_t start_layers_manager(void)
net_layer *layer;
g_joker_token = string_to_token("*");
g_layers_trace_attr = string_to_token("layers_trace");
g_layers.first = NULL;
@ -132,7 +132,7 @@ status_t stop_layers_manager(void)
// #pragma mark [Public functions]
// #pragma mark -
// --------------------------------------------------
status_t register_layer(const char *name, const char *type, int priority,
@ -243,41 +243,53 @@ net_layer * find_layer(const char *name)
return layer;
}
// #pragma mark -
// --------------------------------------------------
status_t add_layer_attribute(net_layer *layer, const void *id, int type, ...)
{
status_t status;
va_list args;
va_start(args, type);
switch(type) {
case NET_ATTRIBUTE_DATA:
// hack
layer->cookie = va_arg(args, void *);
break;
}
status = add_attribute(&layer->attributes, id, type, args);
va_end(args);
return B_OK;
return status;
}
// --------------------------------------------------
status_t remove_layer_attribute(net_layer *layer, const void *id)
status_t remove_layer_attribute(net_layer *layer, const void *id, int index)
{
return B_ERROR;
net_attribute *attr;
if (! layer)
return B_BAD_VALUE;
attr = find_attribute(layer->attributes, id, index, NULL, NULL, NULL);
if (! attr)
return B_NAME_NOT_FOUND;
return delete_attribute(attr, &layer->attributes);
}
status_t find_layer_attribute(net_layer *layer, const void *id, int *type,
void **attribute, size_t *size)
status_t find_layer_attribute(net_layer *layer, const void *id, int index, int *type,
void **value, size_t *size)
{
*attribute = &layer->cookie;
net_attribute *attr;
if (! layer)
return B_BAD_VALUE;
attr = find_attribute(layer->attributes, id, index, type, value, size);
if (! attr)
return B_NAME_NOT_FOUND;
return B_OK;
}
// #pragma mark -
// --------------------------------------------------
status_t send_layers_up(net_layer *layer, net_buffer *buffer)
@ -289,6 +301,8 @@ status_t send_layers_up(net_layer *layer, net_buffer *buffer)
if (!layer)
return B_ERROR;
add_buffer_attribute(buffer, g_layers_trace_attr, NET_ATTRIBUTE_STRING, layer->name),
status = acquire_sem(g_layers.lock);
if (status != B_OK)
return status;
@ -344,10 +358,13 @@ status_t send_layers_down(net_layer *layer, net_buffer *buffer)
if (!layer)
return B_ERROR;
// #### TODO: lock the layer(s) above & below hierarchy
if (!layer->layers_below)
// no layers below this one
return B_ERROR;
add_buffer_attribute(buffer, g_layers_trace_attr, NET_ATTRIBUTE_STRING, layer->name),
status = B_ERROR;
i = 0;
@ -358,15 +375,17 @@ status_t send_layers_down(net_layer *layer, net_buffer *buffer)
continue;
status = below->module->process_output(below, buffer);
if (status == B_OK)
if (status == B_OK) {
atomic_add(&below->use_count, 1);
// TODO: resort this layer with previous one, if required.
return status;
};
};
return status;
}
// #pragma mark [Private functions]
// #pragma mark -
// --------------------------------------------------
static net_layer * new_layer(const char *name, const char *type, int priority,
@ -405,6 +424,8 @@ static net_layer * new_layer(const char *name, const char *type, int priority,
layer->layers_above = NULL;
layer->layers_below = NULL;
layer->attributes = NULL;
return layer;
}
@ -427,7 +448,21 @@ static status_t delete_layer(net_layer *layer)
free(layer->layers_above);
if (layer->layers_below)
free(layer->layers_below);
if (layer->attributes) {
// Free layer attributes
net_attribute *attr;
net_attribute *next_attr;
attr = layer->attributes;
while (attr) {
next_attr = attr->next;
delete_attribute(attr, NULL);
attr = next_attr;
};
};
return g_memory_pool->delete_pool_node(g_layers_pool, layer);
}

View File

@ -20,8 +20,8 @@ extern status_t unregister_layer(net_layer *layer);
extern net_layer * find_layer(const char *name);
extern status_t add_layer_attribute(net_layer *layer, const void *id, int type, ...);
extern status_t remove_layer_attribute(net_layer *layer, const void *id);
extern status_t find_layer_attribute(net_layer *layer, const void *id,
extern status_t remove_layer_attribute(net_layer *layer, const void *id, int index);
extern status_t find_layer_attribute(net_layer *layer, const void *id, int index,
int *type, void **attribute, size_t *size);
extern status_t send_layers_up(net_layer *me, struct net_buffer *buffer);