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