datalink.[c|h] -> layers_manager.[c|h]
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3806 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -179,6 +179,8 @@ status_t delete_buffer(net_buffer *buffer, bool interrupt_safe)
|
|||||||
// Uh? From where come this net_data!?!
|
// Uh? From where come this net_data!?!
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
|
printf("delete_buffer(%p)\n", buffer);
|
||||||
|
|
||||||
if (interrupt_safe) {
|
if (interrupt_safe) {
|
||||||
// We're called from a interrupt handler. Don't use any blocking calls (delete_pool_node() is!)
|
// We're called from a interrupt handler. Don't use any blocking calls (delete_pool_node() is!)
|
||||||
// We flag this net_buffer as to be free by the buffers purgatory thread
|
// We flag this net_buffer as to be free by the buffers purgatory thread
|
||||||
@@ -877,7 +879,7 @@ void dump_memory
|
|||||||
|
|
||||||
for (j = i; j < len && j < i+16;j++)
|
for (j = i; j < len && j < i+16;j++)
|
||||||
{
|
{
|
||||||
if ( byte[j] >= ' ' && byte[j] <= 0x7e )
|
if ( byte[j] >= ' ' && byte[j] < 0x7e )
|
||||||
*ptr = byte[j];
|
*ptr = byte[j];
|
||||||
else
|
else
|
||||||
*ptr = '.';
|
*ptr = '.';
|
||||||
|
|||||||
@@ -0,0 +1,270 @@
|
|||||||
|
/* layers_manager.c */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include <KernelExport.h>
|
||||||
|
#include <OS.h>
|
||||||
|
|
||||||
|
#include "layers_manager.h"
|
||||||
|
#include "buffer.h"
|
||||||
|
|
||||||
|
/* Defines we need */
|
||||||
|
#define NET_LAYER_MODULES_ROOT "network/layers/"
|
||||||
|
|
||||||
|
struct layers_list {
|
||||||
|
net_layer *first;
|
||||||
|
sem_id lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct layers_list g_layers;
|
||||||
|
|
||||||
|
// #pragma mark [Start/Stop functions]
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
status_t start_layers_manager()
|
||||||
|
{
|
||||||
|
void *module_list;
|
||||||
|
net_layer *layer;
|
||||||
|
|
||||||
|
g_layers.first = NULL;
|
||||||
|
|
||||||
|
g_layers.lock = create_sem(1, "net_layers list lock");
|
||||||
|
if (g_layers.lock < B_OK)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
#ifdef _KERNEL_MODE
|
||||||
|
set_sem_owner(g_layers.lock, B_SYSTEM_TEAM);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Load all network/interfaces/* modules and let them
|
||||||
|
// register any layer they may support by calling init()
|
||||||
|
module_list = open_module_list(NET_LAYER_MODULES_ROOT);
|
||||||
|
if (module_list) {
|
||||||
|
size_t sz;
|
||||||
|
char module_name[256];
|
||||||
|
struct net_layer_module_info *nlmi;
|
||||||
|
|
||||||
|
sz = sizeof(module_name);
|
||||||
|
while(read_next_module_name(module_list, module_name, &sz) == B_OK) {
|
||||||
|
sz = sizeof(module_name);
|
||||||
|
if (!strlen(module_name))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (get_module(module_name, (module_info **) &nlmi) != B_OK)
|
||||||
|
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()
|
||||||
|
put_module(module_name);
|
||||||
|
};
|
||||||
|
close_module_list(module_list);
|
||||||
|
};
|
||||||
|
|
||||||
|
// auto-start layer(s)
|
||||||
|
acquire_sem(g_layers.lock);
|
||||||
|
layer = g_layers.first;
|
||||||
|
while (layer) {
|
||||||
|
layer->module->enable(layer, true);
|
||||||
|
layer = layer->next;
|
||||||
|
};
|
||||||
|
release_sem(g_layers.lock);
|
||||||
|
|
||||||
|
puts("net layers manager started.");
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
status_t stop_layers_manager()
|
||||||
|
{
|
||||||
|
net_layer *layer, *next;
|
||||||
|
const char *module_name;
|
||||||
|
|
||||||
|
delete_sem(g_layers.lock);
|
||||||
|
g_layers.lock = -1;
|
||||||
|
|
||||||
|
// TODO: handle multiple layers registered by same net module
|
||||||
|
|
||||||
|
// unregister all layers...
|
||||||
|
layer = g_layers.first;
|
||||||
|
while (layer) {
|
||||||
|
next = layer->next;
|
||||||
|
module_name = layer->module->info.name;
|
||||||
|
printf("layers_manager: uniniting '%s' layer\n", layer->name);
|
||||||
|
// down the layer if currently up
|
||||||
|
layer->module->enable(layer, false);
|
||||||
|
layer->module->uninit(layer);
|
||||||
|
printf("layers_manager: unloading %s layer(s) module\n", module_name);
|
||||||
|
put_module(module_name);
|
||||||
|
layer = next;
|
||||||
|
};
|
||||||
|
|
||||||
|
puts("net layers manager stopped.");
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark [Public functions]
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
status_t register_layer(net_layer *layer)
|
||||||
|
{
|
||||||
|
status_t status;
|
||||||
|
module_info *dummy;
|
||||||
|
|
||||||
|
if (!layer)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
if (layer->module == NULL)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
// acquire this module, to keep it loaded while this layer is registered
|
||||||
|
status = get_module(layer->module->info.name, &dummy);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
layer->layers_above = NULL;
|
||||||
|
layer->layers_below = NULL;
|
||||||
|
|
||||||
|
status = acquire_sem(g_layers.lock);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
layer->next = g_layers.first;
|
||||||
|
g_layers.first = layer;
|
||||||
|
|
||||||
|
release_sem(g_layers.lock);
|
||||||
|
|
||||||
|
|
||||||
|
printf("layers_manager: '%s' layer registered\n", layer->name);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
status_t unregister_layer(net_layer *layer)
|
||||||
|
{
|
||||||
|
status_t status;
|
||||||
|
|
||||||
|
if (!layer)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
status = acquire_sem(g_layers.lock);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
if (g_layers.first == layer)
|
||||||
|
g_layers.first = layer->next;
|
||||||
|
else {
|
||||||
|
net_layer * p = g_layers.first;
|
||||||
|
while (p && p->next != layer)
|
||||||
|
p = p->next;
|
||||||
|
|
||||||
|
if (!p)
|
||||||
|
printf("layers_manager: unregister_layer(): %p layer not found in list!\n", layer);
|
||||||
|
else
|
||||||
|
p->next = layer->next;
|
||||||
|
};
|
||||||
|
|
||||||
|
release_sem(g_layers.lock);
|
||||||
|
|
||||||
|
printf("layers_manager: '%s' layer unregistered\n", layer->name);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
status_t push_buffer_up(net_layer *layer, net_buffer *buffer)
|
||||||
|
{
|
||||||
|
net_layer *above;
|
||||||
|
status_t status;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!layer)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
// #### TODO: lock the layer(s) above & below hierarchy
|
||||||
|
if (!layer->layers_above)
|
||||||
|
// no layers above this one
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
status = B_ERROR;
|
||||||
|
i = 0;
|
||||||
|
while (layer->layers_above[i]) {
|
||||||
|
above = layer->layers_above[i++];
|
||||||
|
if (!above->module->input_buffer)
|
||||||
|
// this layer don't input buffer
|
||||||
|
continue;
|
||||||
|
|
||||||
|
status = above->module->input_buffer(above, buffer);
|
||||||
|
if (status == B_OK)
|
||||||
|
return status;
|
||||||
|
};
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t push_buffer_down(net_layer *layer, net_buffer *buffer)
|
||||||
|
{
|
||||||
|
net_layer *below;
|
||||||
|
status_t status;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
status = B_ERROR;
|
||||||
|
i = 0;
|
||||||
|
while (layer->layers_below[i]) {
|
||||||
|
below = layer->layers_below[i++];
|
||||||
|
if (!below->module->output_buffer)
|
||||||
|
// this layer don't output buffer
|
||||||
|
continue;
|
||||||
|
|
||||||
|
status = below->module->output_buffer(below, buffer);
|
||||||
|
if (status == B_OK)
|
||||||
|
return status;
|
||||||
|
};
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark [Private functions]
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// ----------------------------------------------------
|
||||||
|
status_t interface_reader(void *args)
|
||||||
|
{
|
||||||
|
ifnet_t *iface = args;
|
||||||
|
net_buffer *buffer;
|
||||||
|
status_t status;
|
||||||
|
|
||||||
|
if (!iface || iface->module == NULL)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
while(iface->if_flags & IFF_UP) {
|
||||||
|
buffer = NULL;
|
||||||
|
status = iface->module->receive_buffer(iface, &buffer);
|
||||||
|
if (status < B_OK || buffer == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
dump_buffer(buffer);
|
||||||
|
delete_buffer(buffer, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/* layers_manager.h
|
||||||
|
* private definitions for network layers manager
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OBOS_NET_STACK_LAYERS_MANAGER_H
|
||||||
|
#define OBOS_NET_STACK_LAYERS_MANAGER_H
|
||||||
|
|
||||||
|
#include "net_layer.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern status_t start_layers_manager();
|
||||||
|
extern status_t stop_layers_manager();
|
||||||
|
|
||||||
|
extern status_t register_layer(net_layer *layer);
|
||||||
|
extern status_t unregister_layer(net_layer *layer);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* OBOS_NET_STACK_LAYERS_MANAGER_H */
|
||||||
@@ -11,15 +11,10 @@
|
|||||||
#include "net_stack.h"
|
#include "net_stack.h"
|
||||||
#include "memory_pool.h"
|
#include "memory_pool.h"
|
||||||
|
|
||||||
#include "datalink.h"
|
#include "layers_manager.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
/* Defines we need */
|
|
||||||
#define NETWORK_INTERFACES "network/interfaces"
|
|
||||||
#define NETWORK_PROTOCOLS "network/protocols"
|
|
||||||
#define PPP_DEVICES "ppp/devices"
|
|
||||||
|
|
||||||
struct memory_pool_module_info *g_memory_pool = NULL;
|
struct memory_pool_module_info *g_memory_pool = NULL;
|
||||||
static bool g_started = false;
|
static bool g_started = false;
|
||||||
|
|
||||||
@@ -39,7 +34,7 @@ static status_t start(void)
|
|||||||
start_buffers_service();
|
start_buffers_service();
|
||||||
start_timers_service();
|
start_timers_service();
|
||||||
|
|
||||||
start_datalink_layer();
|
start_layers_manager();
|
||||||
|
|
||||||
puts("stack: started.");
|
puts("stack: started.");
|
||||||
g_started = true;
|
g_started = true;
|
||||||
@@ -51,7 +46,7 @@ static status_t stop(void)
|
|||||||
{
|
{
|
||||||
puts("stack: stopping...");
|
puts("stack: stopping...");
|
||||||
|
|
||||||
stop_datalink_layer();
|
stop_layers_manager();
|
||||||
|
|
||||||
stop_timers_service();
|
stop_timers_service();
|
||||||
stop_buffers_service();
|
stop_buffers_service();
|
||||||
@@ -75,9 +70,12 @@ struct net_stack_module_info nsmi = {
|
|||||||
start,
|
start,
|
||||||
stop,
|
stop,
|
||||||
|
|
||||||
// Data-Link layer
|
// Layers handling
|
||||||
register_interface,
|
register_layer,
|
||||||
unregister_interface,
|
unregister_layer,
|
||||||
|
|
||||||
|
push_buffer_up,
|
||||||
|
push_buffer_down,
|
||||||
|
|
||||||
// net_buffer support
|
// net_buffer support
|
||||||
new_buffer,
|
new_buffer,
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user