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