As Jan already mentioned, the patch was an error. I tried to fix it: the version
attached here should apply cleanly, but I did not try it out, since I do not use
it anymore. It provides (roughly) what I think you need. Use it with a grain of
salt, please :-)

I suspect, that you will get into trouble when multiple handlers qualify for a
single packet. All of them would now try to free the SKB at the end which would
be an error. Otherwise, it should work.

Regards,
        Petr Grillinger

Qeltaras wrote:
> I try to install the patch, but the sistem returned me this error:
> 
> patching file stack/stack_mgr.c
> Hunk #1 succeeded at 46 with fuzz 2.
> Hunk #2 FAILED at 76.
> 
> parch: **** malformed patch at line 126:
> 
> On 5/30/05, Petr Grillinger <[EMAIL PROTECTED]> wrote:
> 
diff -urNp -x '\.*' -x '*.[ao]' rtnet-0.8.0/stack/include/stack_mgr.h 
rtnet-0.8.0-pg/stack/include/stack_mgr.h
--- rtnet-0.8.0/stack/include/stack_mgr.h       2005-06-06 12:41:02.000000000 
+0200
+++ rtnet-0.8.0-pg/stack/include/stack_mgr.h    2005-06-06 12:44:35.000000000 
+0200
@@ -40,6 +40,8 @@ struct rtpacket_type {
     int            (*handler)(struct rtskb *, struct rtpacket_type *);
     int            (*err_handler)(struct rtskb *, struct rtnet_device *,
                                   struct rtpacket_type *);
+    int            ifindex;
+    struct rtpacket_type *next;
 };
 
 
diff -urNp -x '\.*' -x '*.[ao]' rtnet-0.8.0/stack/packet/af_packet.c 
rtnet-0.8.0-pg/stack/packet/af_packet.c
--- rtnet-0.8.0/stack/packet/af_packet.c        2005-06-06 12:41:02.000000000 
+0200
+++ rtnet-0.8.0-pg/stack/packet/af_packet.c     2005-06-06 12:50:59.000000000 
+0200
@@ -36,16 +36,16 @@ int rt_packet_rcv(struct rtskb *skb, str
 {
     struct rtsocket *sock = (struct rtsocket *)(((u8 *)pt) -
                                 ((u8 *)&((struct rtsocket *)0)->prot.packet));
-    int             ifindex = sock->prot.packet.ifindex;
     void            (*callback_func)(struct rtdm_dev_context *, void *);
     void            *callback_arg;
     unsigned long   flags;
 
 
-    if (((ifindex != 0) && (ifindex != skb->rtdev->ifindex)) ||
-        (rtskb_acquire(skb, &sock->skb_pool) != 0))
+    if (rtskb_acquire(skb, &sock->skb_pool) != 0) {
         kfree_rtskb(skb);
-    else {
+       rtos_print("Cannot acquire rtskb\n");
+       return -ENOMEM;
+    } else {
         rtdev_reference(skb->rtdev);
         rtskb_queue_tail(&sock->incoming, skb);
         rtos_event_sem_signal(&sock->wakeup_event);
@@ -91,6 +91,7 @@ int rt_packet_bind(struct rtsocket *sock
     }
 
     pt->type = new_type;
+    pt->ifindex = sll->sll_ifindex;
     sock->prot.packet.ifindex = sll->sll_ifindex;
 
     /* if protocol is non-zero, register the packet type */
diff -urNp -x '\.*' -x '*.[ao]' rtnet-0.8.0/stack/stack_mgr.c 
rtnet-0.8.0-pg/stack/stack_mgr.c
--- rtnet-0.8.0/stack/stack_mgr.c       2005-06-06 12:41:02.000000000 +0200
+++ rtnet-0.8.0-pg/stack/stack_mgr.c    2005-06-06 12:59:02.000000000 +0200
@@ -46,20 +46,12 @@ int rtdev_add_pack(struct rtpacket_type 
 
     rtos_spin_lock_irqsave(&rt_packets_lock, flags);
 
-    if (rt_packets[hash] == NULL) {
-        rt_packets[hash] = pt;
-
-        pt->refcount = 0;
-
-        rtos_spin_unlock_irqrestore(&rt_packets_lock, flags);
-
-        return 0;
-    }
-    else {
-        rtos_spin_unlock_irqrestore(&rt_packets_lock, flags);
-
-        return -EADDRNOTAVAIL;
-    }
+    pt->next = rt_packets[hash];
+    rt_packets[hash] = pt;
+    pt->refcount = 0;
+ 
+    rtos_spin_unlock_irqrestore(&rt_packets_lock, flags);
+    return 0;
 }
 
 
@@ -84,22 +76,22 @@ int rtdev_remove_pack(struct rtpacket_ty
 
     rtos_spin_lock_irqsave(&rt_packets_lock, flags);
 
-    if ((rt_packets[hash] != NULL) &&
-        (rt_packets[hash]->type == pt->type)) {
-        rt_packets[hash] = NULL;
-
-        if (pt->refcount > 0)
-            ret = -EAGAIN;
-
-        rtos_spin_unlock_irqrestore(&rt_packets_lock, flags);
-
-        return ret;
+    struct rtpacket_type **rtp = &(rt_packets[hash]);
+    
+    while ((*rtp) != NULL) {
+        if (*rtp == pt) {
+           *rtp = pt->next;
+           if (pt->refcount > 0)
+                ret = -EAGAIN;
+           goto ende; 
+        }
+        rtp = &((*rtp)->next);
     }
-    else {
-        rtos_spin_unlock_irqrestore(&rt_packets_lock, flags);
+    ret = -ENOENT;
 
-        return -ENOENT;
-    }
+ende:
+    rtos_spin_unlock_irqrestore(&rt_packets_lock, flags);
+    return ret;
 }
 
 
@@ -185,29 +177,41 @@ static void do_stacktask(int mgr_id)
             hash = ntohs(skb->protocol) & (MAX_RT_PROTOCOLS-1);
 
             rtos_spin_lock_irqsave(&rt_packets_lock, flags);
-
             pt = rt_packets[hash];
 
-            if ((pt != NULL) && (pt->type == skb->protocol)) {
-                pt->refcount++;
-                rtos_spin_unlock_irqrestore(&rt_packets_lock, flags);
-
-                pt->handler(skb, pt);
-
-                rtos_spin_lock_irqsave(&rt_packets_lock, flags);
-                pt->refcount--;
-                rtos_spin_unlock_irqrestore(&rt_packets_lock, flags);
-            } else {
-                rtos_spin_unlock_irqrestore(&rt_packets_lock, flags);
-
-                /* don't warn if running in promiscuous mode (RTcap...?) */
-                if ((rtdev->flags & IFF_PROMISC) == 0)
-                    rtos_print("RTnet: unknown layer-3 protocol\n");
-
-                kfree_rtskb(skb);
+            int proto_cnt = 0, 
+                if_cnt = 0;
+            for ( ; pt; pt = pt->next) {
+                if (pt->type == skb->protocol) {
+                    if (!pt->ifindex || pt->ifindex == skb->rtdev->ifindex) { 
+                        pt->refcount++;
+                        rtos_spin_unlock_irqrestore(&rt_packets_lock, flags);
+
+                        pt->handler(skb, pt);
+
+                        rtos_spin_lock_irqsave(&rt_packets_lock, flags);
+                        pt->refcount--;
+                        if_cnt++;
+                    } 
+                    proto_cnt++;
+                }
+            }
+            rtos_spin_unlock_irqrestore(&rt_packets_lock, flags);
+            
+            /* don't warn if running in promiscuous mode (RTcap...?) */
+            if ((rtdev->flags & IFF_PROMISC) == 0) {
+                if (proto_cnt == 0)
+                    rtos_print("RTnet: missing handler for protocol 0x%04x\n", 
+                            ntohs(skb->protocol));
+                else if (if_cnt == 0)
+                    rtos_print("RTnet: missing handler for protocol 0x%04x, 
interface %d\n", 
+                            ntohs(skb->protocol), skb->rtdev->ifindex);
             }
 
-            rtdev_dereference(rtdev);
+           if (!if_cnt) {  /* packet not handled */
+               kfree_rtskb(skb);
+               rtdev_dereference(rtdev);
+           }
         }
     }
 }

Reply via email to