On 7/29/06, Jan Kiszka <[EMAIL PROTECTED]> wrote:
> Marco Pantaleoni wrote:
> > Hi,
> > I'm writing an application using rtnet 0.9.3 and vulcano CVS (using LXRT)
> > that should send and receive raw ethernet frames from multiple NICs. I've
> > followed the raw-packet Xenomai example to understand how to open the raw
> > socket and how to use it. All works flawlessly when I open a single socket
> > and send/receive frames from the single interface bound to the socket. But
> > if I try to open an additional socket (with the intention of binding it
> > to a
> > second NIC), then the rt_dev_socket() call fails returning -EADDRNOTAVAIL
> > (-99).
> > The exact call that fails is identical to the first, successful, one:
> >
> > ret = rt_dev_socket(AF_PACKET, SOCK_DGRAM, htons(PROTOCOL));
> >
> > Changing PROTOCOL in the second call doesn't help.
> > I wonder if rtnet allows to open only one raw socket at a time.
> > (I'm to using RTmac, or anything else, because I don't need the
> > higher-level
> > protocols).
>
> The first behaviour is explainable as only one listener can register on
> the same protocol so far. The original packet demultiplexer design
> supported even only one listener per hash value. This restriction has
> been remove some time ago, but no one yet asked for enhancing the
> interface for a scenario like yours.
>
> The second oddity remains strange (different protocols must be feasible
> already). Please re-check if you _really_ tried to register _different_
> protocol numbers.

Hi Jan,
I've checked again, and you are right: changing protocol number in the
second call make it work (both with and without your patch). Perhaps
the first time I did something wrong.

> >
> > Do you have any explanation or suggestion?
>
> Give attached patch a try. To do so, run in your rtnet directory:
>
> patch -p1 -i multi-af_packet-listeners.patch
>
> Then recompile RTnet. Note that I only compile-tested this extension
> yet, so I count on YOU to give feedback if it works or breaks anything.
> Once I got your ok and that damn server at berlios.de gained some disk
> space again, I will commit the patch to SVN for 0.9.4.

Done, it works. Now I can open more than one socket using the same
protocol number.

But I have another couple of problems now. Let me introduce some more
background: I have in the same machine one 3Com (eth0), and 6 Realtek
8139, of which the first three are allocated to rtnet and the
remaining to standard linux (using cards=1,1,1,0,0,0). When everything
is loaded, the NIC <-> IRQ mapping is the following:

NIC      IRQ
rteth0   21
rteth1   23
rteth2   22
eth0     16
eth1     19
eth2     21
eth3     23

Now if I send raw ethernet frames (with a cross cable) from any one of
the rteth* NICs to eth0 or eth1, I can see the incoming packets with
tcpdump. If I send to eth2 or eth3 I don't see nothing. I guess this
is due to IRQ sharing. Can you confirm this? Is there anything I can
do about it?
But the strange thing (for me at least), is that if I send the raw
frames from rteth0 to rteth1 or rteth2 (the RT program has two tasks:
one sending and one receiving, the reasone for having more than one
raw socket...), I don't receive anything.
I guess I'm doing somethins stupid in the code here.
The setup code (simplified, with error checking removed) is:

    sock_tx = rt_dev_socket(AF_PACKET, SOCK_DGRAM, htons(PROTOCOL));
    memset(&local_addr_tx, 0, sizeof(struct sockaddr_ll));
    local_addr_tx.sll_family   = AF_PACKET;             /* always AF_PACKET */
    local_addr_tx.sll_protocol = htons(PROTOCOL);       /* Physical
layer protocol */
    local_addr_tx.sll_ifindex  = txif;                  /* Interface number */
    ret = rt_dev_bind(sock_tx, (struct sockaddr *)&local_addr_tx,
sizeof(struct sockaddr_ll));

    sock_rx = rt_dev_socket(AF_PACKET, SOCK_DGRAM, htons(PROTOCOL));
    memset(&local_addr_rx, 0, sizeof(struct sockaddr_ll));
    local_addr_rx.sll_family   = AF_PACKET;             /* always AF_PACKET */
    local_addr_rx.sll_protocol = htons(PROTOCOL);       /* Physical
layer protocol */
    local_addr_rx.sll_ifindex  = rxif;                  /* Interface number */
    ret = rt_dev_bind(sock_rx, (struct sockaddr *)&local_addr_rx,
sizeof(struct sockaddr_ll));

    tmout = -2;  /* negative: force non-blocking behaviour */
    ret = rt_dev_ioctl(sock_rx, RTNET_RTIOC_TIMEOUT, &tmout);

    memset(&dest_addr, 0, sizeof(struct sockaddr_ll));
    dest_addr.sll_family   = AF_PACKET;                 /* always AF_PACKET */
    dest_addr.sll_protocol = htons(PROTOCOL);           /* Physical
layer protocol */
    dest_addr.sll_ifindex  = dest_if;                  /* Interface number */
    dest_addr.sll_halen    = 6;                         /* Length of address */
    my_eth_aton(dest_addr.sll_addr, destination_mac);   /* Physical
layer address */

I've tried either with dest_if set to rxif and dest_if set to txif. In
the former case something happens: I succesfully send the first 16
frames, and get -ENOBUFS (-105) for the subsequent ones. But in both
cases nothing is received by rt_recvmsg().
What I'm missing here?

One last thing: as the interface index (for sll_ifindex) I've to use 2
for rteth0, 3 for rteth1, ... which seems off by 1. Is there any
explanation?

Thank you again for your support and patience!
Cheers,
Marco

-- 
Marco Pantaleoni

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
RTnet-users mailing list
RTnet-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rtnet-users

Reply via email to