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