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.

> 
> 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.

Jan
---
 stack/include/stack_mgr.h |    3 ++-
 stack/ipv4/ip_input.c     |    5 +++--
 stack/packet/af_packet.c  |    6 ++++--
 stack/rtmac/rtmac_proto.c |    7 ++++---
 stack/stack_mgr.c         |   18 ++++++------------
 5 files changed, 19 insertions(+), 20 deletions(-)

Index: rtnet/stack/include/stack_mgr.h
===================================================================
--- rtnet.orig/stack/include/stack_mgr.h
+++ rtnet/stack/include/stack_mgr.h
@@ -41,6 +41,8 @@
 #define RTPACKET_HASH_KEY_MASK  (RTPACKET_HASH_TBL_SIZE-1)
 
 struct rtpacket_type {
+    struct list_head    list_entry;
+
     unsigned short      type;
     short               refcount;
 
@@ -49,7 +51,6 @@ struct rtpacket_type {
                                        struct rtpacket_type *);
 
     char                *name;
-    struct list_head    list_entry;
 };
 
 
Index: rtnet/stack/ipv4/ip_input.c
===================================================================
--- rtnet.orig/stack/ipv4/ip_input.c
+++ rtnet/stack/ipv4/ip_input.c
@@ -163,11 +163,12 @@ int rt_ip_rcv(struct rtskb *skb, struct 
         return 0;
 #endif /* CONFIG_RTNET_RTIPV4_ROUTER */
 
-    return rt_ip_local_deliver(skb);
+    rt_ip_local_deliver(skb);
+    return 0;
 
   drop:
     kfree_rtskb(skb);
-    return NET_RX_DROP;
+    return 0;
 }
 
 
Index: rtnet/stack/packet/af_packet.c
===================================================================
--- rtnet.orig/stack/packet/af_packet.c
+++ rtnet/stack/packet/af_packet.c
@@ -45,8 +45,10 @@ int rt_packet_rcv(struct rtskb *skb, str
     rtdm_lockctx_t  context;
 
 
-    if (((ifindex != 0) && (ifindex != skb->rtdev->ifindex)) ||
-        (rtskb_acquire(skb, &sock->skb_pool) != 0))
+    if (unlikely((ifindex != 0) && (ifindex != skb->rtdev->ifindex)))
+        return EUNATCH;
+
+    if (unlikely(rtskb_acquire(skb, &sock->skb_pool) != 0))
         kfree_rtskb(skb);
     else {
         rtdev_reference(skb->rtdev);
Index: rtnet/stack/rtmac/rtmac_proto.c
===================================================================
--- rtnet.orig/stack/rtmac/rtmac_proto.c
+++ rtnet/stack/rtmac/rtmac_proto.c
@@ -55,13 +55,14 @@ int rtmac_proto_rx(struct rtskb *skb, st
     }
 
     if (hdr->flags & RTMAC_FLAG_TUNNEL)
-        return rtmac_vnic_rx(skb, hdr->type);
+        rtmac_vnic_rx(skb, hdr->type);
     else if (disc->disc_type == hdr->type)
-        return disc->packet_rx(skb);
+        disc->packet_rx(skb);
+    return 0;
 
   error:
     kfree_rtskb(skb);
-    return -1;
+    return 0;
 }
 
 
Index: rtnet/stack/stack_mgr.c
===================================================================
--- rtnet.orig/stack/stack_mgr.c
+++ rtnet/stack/stack_mgr.c
@@ -60,16 +60,7 @@ int rtdev_add_pack(struct rtpacket_type 
     hash = ntohs(pt->type) & RTPACKET_HASH_KEY_MASK;
 
     rtdm_lock_get_irqsave(&rt_packets_lock, context);
-
-    list_for_each_entry(pt_entry, &rt_packets[hash], list_entry) {
-        if (unlikely(pt_entry->type == pt->type)) {
-            ret = -EADDRNOTAVAIL;
-            goto unlock_out;
-        }
-    }
     list_add_tail(&pt->list_entry, &rt_packets[hash]);
-
-  unlock_out:
     rtdm_lock_put_irqrestore(&rt_packets_lock, context);
 
     return ret;
@@ -155,6 +146,7 @@ static void stackmgr_task(void *arg)
     struct rtpacket_type    *pt_entry;
     rtdm_lockctx_t          context;
     struct rtnet_device     *rtdev;
+    int                     err;
 
 
     while (rtdm_event_wait(mgr_event) == 0)
@@ -180,21 +172,23 @@ static void stackmgr_task(void *arg)
                     pt_entry->refcount++;
                     rtdm_lock_put_irqrestore(&rt_packets_lock, context);
 
-                    pt_entry->handler(skb, pt_entry);
+                    err = pt_entry->handler(skb, pt_entry);
 
                     rtdm_lock_get_irqsave(&rt_packets_lock, context);
                     pt_entry->refcount--;
                     rtdm_lock_put_irqrestore(&rt_packets_lock, context);
 
                     rtdev_dereference(rtdev);
-                    goto next_packet;
+                    if (!err)
+                        goto next_packet;
                 }
 
             rtdm_lock_put_irqrestore(&rt_packets_lock, context);
 
             /* don't warn if running in promiscuous mode (RTcap...?) */
             if ((rtdev->flags & IFF_PROMISC) == 0)
-                rtdm_printk("RTnet: unknown layer-3 protocol\n");
+                rtdm_printk("RTnet: no one cared for packet with layer 3 "
+                            "protocol type 0x%04x\n", ntohs(skb->protocol));
 
             kfree_rtskb(skb);
             rtdev_dereference(rtdev);

Attachment: signature.asc
Description: OpenPGP digital signature

-------------------------------------------------------------------------
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