Folks,
I’m at my wit’s end or near it. I can’t seem to figure out why my simple
IP_IP filter example hoses up the entire io-net subsystem. I can mount and
unmount it and I get some output indicatig that the init function runs, and
the rx_up and rx_down functions run, and get a few packets. I just want to
pass everythig through but this seems not to work. Is this not enough? My
rx_up function just calls tx_up and my rx_down just calls tx_down. hoses up
the system until I umount /dev/io-net/ip_ip0, then it returns to normal. I
build normally with qcc -shared -Vgcc_ntomipsle
ipfilter.c -oipfilter.so -w9. I don’t strip the output. I can see from the
printouts that go out on my serial console that the functions are all
getting called so the problem seems to be that I am not properly passing the
packets through. If someone could comment on what I am doing wrong, I would
be eternally greatful.
Thanks in advance!
Chris
P.S. I can include output from a sample run if anyone thinks this would
help. I suspect I’ve done something ( or rather NOT done something
obvious… )
// ipfilter.c
// a test to see if I can generate an IP filter that hooks into io-net
// and sees all the packets flowing by in both directions.
//
// The general idea is to hook in as a filter just above the
// tulip driver.
//
// Chris Beasley, Berkeley Process Control, Inc. 2001
//
#include <hw/inout.h>
#include <sys/mman.h>
#include <sys/io-net.h>
#include <inttypes.h>
#include <atomic.h>
#include <unistd.h>
#include <stdio.h>
#include <strings.h>
#include <errno.h>
#include <net/if.h>
#include <net/if_types.h>
int my_init( void *dll_hdl,
dispatch_t *dpp,
io_net_self_t *ion,
char *options );
void *my_rx_thread( void *arg );
int my_tx_done( npkt_t *npkt, void *done_hdl, void *func_hdl );
int my_rx_up( npkt_t *npkt,
void *func_hdl,
int off,
int framlen_sub,
uint16_t cell,
uint16_t endpoint,
uint16_t iface );
int my_rx_down( npkt_t *npkt, void *func_hdl );
int my_shutdown1( int registrant_hdl, void *func_hdl );
int my_shutdown2( int registrant_hdl, void *func_hdl );
// Global symbols
void *my_dll_hdl;
io_net_self_t *my_ion;
int my_reg_hdl;
uint16_t my_cell;
uint16_t my_endpoint;
io_net_dll_entry_t io_net_dll_entry =
{
2, // Number of functions
my_init, // init()
NULL // “master” shutdown()
};
// functions that we supply
io_net_registrant_funcs_t my_funcs =
{
_IO_NET_REG_NFUNCS, // nfuncs
my_rx_up, // receive a packet on it’s way up
my_rx_down, // receive a packet on it’s way down
my_tx_done, // release our hold a packet
my_shutdown1, // shutdown1()
my_shutdown2, // shutdown2()
NULL, // dl_advert()
NULL, // devctl()
NULL, // flush()
NULL, // raw_open()
NULL
};
// a description of our driver
io_net_registrant_t my_entry =
{
_REG_FILTER_BELOW, // | _REG_INIT_ONCE, where the f#(% is _init_once
defined!?
“bpc-ip-filter.so”,// our name
“ip”, // our top type
“ip”, // our bottom type
NULL, // global control handle
&my_funcs, // pointer to our functions
0 // #dependencies
};
// The dll functions.
int my_init (void *dll_hdl, dispatch_t *dpp, io_net_self_t *ion, char
*options)
{
printf( “my_init\n” );
my_dll_hdl = dll_hdl;
my_ion = ion;
// Register with io-net
if ((*my_ion → reg)
(my_dll_hdl,
&my_entry,
&my_reg_hdl,
&my_cell,
&my_endpoint) < 0)
{
return( -1 );
}
return (0); // success
}
file://debug functions
int parse_npkt( npkt_t *npkt )
{
uint16_t *type;
if ( npkt->flags & _NPKT_NOT_TXED )
printf( "not transmitted " );
if ( npkt->flags & _NPKT_NO_RES )
printf( "up producer wants packet back NOW " );
if ( npkt->flags & _NPKT_UP )
printf( "up " );
else
printf( "down " );
if ( npkt->flags & _NPKT_MSG )
printf( "message " );
if ( npkt->flags & _NPKT_MSG_DYING )
printf( "dying " );
if ( npkt->flags & _NPKT_BCAST )
printf( "broadcast " );
if ( npkt->flags & _NPKT_MCAST )
printf( "multicast " );
if ( npkt->flags & _NPKT_INTERNAL )
printf( "internal " );
if ( npkt->flags & _NPKT_UP_SPECIFIC )
printf( "up specific " );
type = (uint16_t *)(npkt->buffers.tqh_first->net_iov->iov_base);
switch ( *type )
{
case _IO_NET_MSG_DL_ADVERT:
printf( ":advert " );
break;
case _IO_NET_MSG_ADDR_ADD:
printf( ":message add " );
break;
case _IO_NET_MSG_ADDR_DEL:
printf( ":message del " );
break;
case QNET_IMMSG_IFUP:
printf( ":qnet ifup " );
break;
case QNET_IMMSG_IFDOWN:
printf( ":nqet ifdown " );
break;
case _IO_NET_JOIN_MCAST:
printf( ":join mcast " );
break;
case _IO_NET_REMOVE_MCAST:
printf( ":remove mcast " );
break;
}
printf( “\n\n” );
return 0;
}
int my_tx_done( npkt_t *npkt, void *done_hdl, void *func_hdl )
{
printf( “my_tx_done\n” );
parse_npkt( npkt );
return 0;
}
int my_rx_up( npkt_t *npkt,
void *func_hdl,
int off,
int framlen_sub,
uint16_t cell,
uint16_t endpoint,
uint16_t iface )
{
printf( “my_rx_up\n” );
parse_npkt( npkt );
(*my_ion->tx_up)( my_reg_hdl, npkt, off, framlen_sub, cell, endpoint,
iface );
return EOK;
}
int my_rx_down( npkt_t *npkt, void *func_hdl )
{
printf( “my_rx_down\n” );
parse_npkt( npkt );
return (*my_ion->tx_down)( my_reg_hdl, npkt );
}
int my_shutdown1( int registrant_hdl, void *func_hdl )
{
printf( “my_shutdown1\n” );
return EOK; // return EBUSY if we don’t want them to shut us down yet
}
int my_shutdown2( int registrant_hdl, void *func_hdl )
{
printf( “my_shutdown2\n” );
return 0; // at this point, we have no choice and must shutdown
}