Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 Mar 2002 10:16:31 -0800
From:      Maksim Yevmenkin <myevmenk@digisle.net>
To:        freebsd-current@freebsd.org, freebsd-net@freebsd.org
Subject:   Flow control in -current Netgraph (long)
Message-ID:  <3CA4AF7F.4B0A1C93@digisle.net>

next in thread | raw e-mail | index | archive | help
Hackers,

i'm writing Bluetooth L2CAP sockets layer in Netgraph. the
basic idea is very similar to Netgraph sockets except
L2CAP is a reliable protocol. before L2CAP channel is open,
each peer must negotiate incoming and outgoing MTU for the
channel. so the idea is that each peer sends and receives
datagram of fixed MTU. note that send and receive MTU might
be different. L2CAP protocol also provides protocol/service
multiplexing (PSM) so upper layer protocols can use L2CAP
as a transport (for example SDP, RFCOMM etc.) 

new L2CAP node is created for every Bluetooth unit. L2CAP 
downstream hook is connected to the HCI layer. also L2CAP
node presents four upstream hooks that represents protocols
(i.e. sdp, rfcomm, tcp and orphan - for other protocols).

for now every L2CAP upstream hook of every L2CAP node is 
connected to the same L2CAP sockets layer. so the sockets
layer knows which PSM/unit downstream hook is connected to.
the socket address contains PSM and BDADDR. (BDADDR is a 
Bluetooth unit address similar to MAC address in Ethernet). 

when socket requesting new connection (via connect() call)
new Netgraph control message is sent to appropriate 
downstream hook (based on which address socket was bound 
via bind() and remote peer's address from connect()). the 
L2CAP node responds to control message and eventually socket
goes into CONNECTED state.

now the data transfer is a bit of a problem. currently
i'm using Netgraph NG_SEND_DATA macros to send data from
socket to the L2CAP node. when i do stress testing and
sending data as fast as i can the system runs out of
mbufs. packets gets dropped and everything goes into
unpredictable state. 

bottom line: in order to guarantee reliable L2CAP channel
i must acknowledge every data packet. the upper layer must
not send any more until is gets an acknowledgment. note 
that single L2CAP packet must be fragmented before it can 
be send to the HCI layer. it is not allowed to reorder/mix
fragments on the same physical link.

so, as of now i have three options

1) put data in queue on every layer and try not to overflow
   them. i do not know the easy and fast way to implement
   this. note that upstream hooks may be connected to the
   different nodes and L2CAP node must somehow synchronize
   them and make sure than everyone gets bandwidth.

2) prepend every data mbuf with some soft of envelope and
   as soon as packet was sent acknowledge it by sending 
   Netgraph control message back to sender (using information
   from envelope). i can live with that, but it might be
   confusing. the sender sends data, but gets a message back.

3) convert every send request into Netgraph message and
   as soon as packet was sent acknowledge it by sending
   response message back. i like this too, but there is
   another problem. i can not pass mbuf in Netgraph 
   control message. here is an example: socket layer 
   pru_send function accepts mbuf. it converts it into
   Netgraph message (m_copydata) and sends it to downstream
   hook. lower layer would have to convert it back to
   mbuf (m_copyback) because it wants to fragment it,
   add headers, etc. yuck! 

i would go with option 2 for now unless someone can 
suggest a better way.

thanks
max

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3CA4AF7F.4B0A1C93>