I am not sure if the small patch helps you but you may want to try it out
(version 0.8.0). It is a part of much larger patch, so I am not realy sure if it
works alone (it should), you probably would not want the whole thing.

It uses a linked lists of protocol handlers (just like normal Linux). There is
also a check for the interface where the frame came from.

Good luck,
        Petr Grillinger
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      2004-10-28 18:05:41.000000000 +0200
+++ rtnet-0.8.0-pg/stack/stack_mgr.c    2004-12-27 13:18:42.000000000 +0100
@@ -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 out; 
+        }
+        rtp = &((*rtp)->next);
     }
-    else {
-        rtos_spin_unlock_irqrestore(&rt_packets_lock, flags);
+    ret = -ENOENT;
 
-        return -ENOENT;
-    }
+out:
+    rtos_spin_unlock_irqrestore(&rt_packets_lock, flags);
+    return ret;
 }
 
 
@@ -185,28 +177,38 @@ 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);
+            }
+            kfree_rtskb(skb);
             rtdev_dereference(rtdev);
         }
     }

Reply via email to