Re: [RTnet-developers] Raw Socket
Brought to you by:
bet-frogger,
kiszka
|
From: Jan K. <jan...@we...> - 2006-08-30 15:12:46
|
Jorge Almeida wrote:
> Hello Jan,
> Sorry for the late answer but our mail server is not working very well =
and i don get your e-mail. I see it in the list archives.
Fortunately, I didn't get bored in the meantime. ;)
>=20
> I have a small test program in C++ for the RAW SOCKET but i don have it=
prepared for publication. This week i will make a simple one and send to=
the list/you.
That's fine.
>=20
>=20
> Regarding the ETH_P_ALL issue:
>=20
> I've reached a point that maybe is the solution for the ETH_P_ALL issue=
, but maybe is not the best solution:
>=20
> In the stack manager task, where the rtskb is sended to the correct soc=
ket, defined with some kind of protocol, the rtskb is requeued for anothe=
r queue, this is, the rtskb from the driver queue is removed and sended f=
or the socket queue (right??).
Right. In exchange, the driver RX queue receives an empty skb from the
target socket. If the socket has none, the packet is dropped (and the
skb is recycled). That's the strict resource management I'm often
referring to.
> Like ETH_P_ALL is for any kind of protocol, every rtskb must be sended =
for the socket that defines the ETH_P_ALL protocol and, with the corrent=
implementation, one rtskb only is able to be queued in one socket queue,=
and only one. This is a problem if any socket is ETH_P_ALL.=20
> My ideia is to make a cycle where all the open sockets are checked for =
ETH_P_ALL protocol, and then pass the rtskb to them, but theres a proble=
m with this method, i need to make a copy of the rtskb, and is in that po=
int that i've stucked now.=20
> (Is there any function that makes a rtskb copy? How can i make a rtskb =
copy?)
>=20
> The ideia after the copy is to head queue the copyed rtskb in the drive=
r queue and process it in the regulat way by the rt_packet_rcv function i=
n af_packet.c file, for the socket with ETH_P_ALL flag.
>=20
> This ideia has one weak point. If theres a lot of ETH_P_ALL sockets the=
copy time for all copies can be very exaustive (in real-time contex) but=
the number of ETH_P_ALL sockets, in the major number of applications, is=
very low, the most times only one in each machine, working like a networ=
k sniffer with a dispatcher. And the time for one rtskb copy is not very =
important (I think). So maybe this solution is the best, because we dont =
miss any message in the ETH_P_ALL sockets neither in the other kind of s=
ockets.
>=20
> If anyone has a better idea please explain it now. I'm implementing the=
ETH_P_ALL feauture at the moment and i only have until next friday (my =
boss said :) ).
Well, I would say we should go for two flavours of ETH_P_ALL (and maybe
stop after implementing the first one :)): Variant A only delivers those
packets to a *single* ETH_P_ALL listener if no one else cared for the
protocol when consulting the rt_packets[] table ("fall-through" as
sketched in earlier mails). Variant B would require some rtskb cloning
(either dumb copying or smarter but more complex sharing) and would then
be able to provide "real" ETH_P_ALL for even more than only one listener.=
A is more something to finish till next Friday, B with copying maybe as
well (but rtskb_copy does not exist yet). B with rtskb sharing is
definitely a larger project. I have some ideas on rtskb sharing for
quite a while (also interesting for potential multicast support), but as
they include a refactoring of the sensitive rtskb subsystem, such a
thing cannot be done quickly.
So my question to you: Would variant A already suffice your project's
requirements?
> =20
> Bellow follows an excert of the new for cycle in stack_mgr thread for t=
he ETH_P_ALL feature.
>=20
> This is an excert of the new stack_mgr.c
>=20
> rtcap_report_incoming(skb);
>=20
> skb->nh.raw =3D skb->data;
> /* start new for cycle*/ =20
> //hash for the ETH_P_ALL packets
> hash =3D ETH_P_ALL & RTPACKET_HASH_KEY_MASK;
> rtdm_lock_get_irqsave(&rt_packets_lock, context);
> rt_printk("Before 1st List: hash =3D %d\n",hash);
> //for cycle that runs over all list entries to check if anyone has ETH_=
P_ALL for protocol type
> list_for_each_entry(pt_entry, &rt_packets[hash], list_entry=
)
> { =20
> rt_printk("List entry protocol=3D %d %d name =3D %d\n",=
ntohs(pt_entry->type),hash,strncmp(pt_entry->name,"PACKET_SOCKET",13));
> //the "PACKET_SOCKET" string is defined in line 188 of =
file af_packet.c
> //this string should be replaced by a #define declarati=
on
> if ( likely(ntohs(pt_entry->type) =3D=3D hash &&=20
> (strncmp(pt_entry->name,"PACKET_SOCKET",13)=
=3D=3D 0 )))
> {
> rt_printk("List entry 1 \n");
> pt_entry->refcount++;
> rtdm_lock_put_irqrestore(&rt_packets_lock, context)=
;
> rt_printk("List entry 2 \n");
> err =3D pt_entry->handler(skb, pt_entry);
> rt_printk("List entry 3 \n");
> rtdm_lock_get_irqsave(&rt_packets_lock, context);
> pt_entry->refcount--;
> rtdm_lock_put_irqrestore(&rt_packets_lock, context)=
;
>=20
> }
> }
> rtdm_lock_put_irqrestore(&rt_packets_lock, context);
> /* end new for cycle*/ =20
> rt_printk("Before 2nd List \n");
> hash =3D ntohs(skb->protocol) & RTPACKET_HASH_KEY_MASK;
> rtdm_lock_get_irqsave(&rt_packets_lock, context);
> //for cycle that runs over all list entries
> list_for_each_entry(pt_entry, &rt_packets[hash], list_entry=
)
> if (pt_entry->type =3D=3D skb->protocol) {
>=20
>=20
> Greetings
>=20
>=20
General remark on the code: If you really have to extend to fast path of
all receivers, please make such feature configurable (something like
CONFIG_RTNET_ETH_P_ALL). But I hope we can get away with A which will
likely be acceptable even without an extra switch.
Jan
|