Oliver Thimm
|
Interface specific hooks of protocol driver (lsm-XXX.so) attached with PFIL_TYPE_IFNET are broken in QNX 7
|
Oliver Thimm
04/18/2019 9:05 AM
post119667
|
Interface specific hooks of protocol driver (lsm-XXX.so) attached with PFIL_TYPE_IFNET are broken in QNX 7
Hi,
we are a provider of Industrial Ethernet protocol stack solutions. For the required
high performance low latency communication we have developed an own protocol driver
similar to your "lsm-nraw" which runs in the stack context to bypass the IP layer
but with a much more optimized data exchange to the application. We are using this
implementation on all 6.x versions since QNX 6.4 without any problems. Unfortunately
our implementation seems to be broken in QNX 7 although it is compiled without any
errors.
In our implementation we call pfil_head_get(int af, u_long dlt) with af set to PFIL_TYPE_IFNET
to indicate an interface hook and dlt set to the respective interface pointer according
to http://www.qnx.com/developers/docs/6.4.1/io-pkt_en/user_guide/filtering.html.
Now I have two initial concerns/questions:
1. The interface pointer has to be casted to u_long which obviously is a little bit fishy
on a 64 bit architecture.
2. At some point in time QNX introduced so called Forwarding Information Base (FIB)
support which is documented poorly or more or less not at all. In the header <pfil.h> which
is included to build our protocol driver the define QNX_MFIB changes the
hook prototype as first argument of pfil_add_hook() from
int (*func)(void *, struct mbuf **, struct ifnet *, int)
into
int (*func)(void *, struct mbuf **, struct ifnet *, int, int)
The last parameter seems to be FIB related. How can one figure out at compile time
how QNX is built or where is this build option for the different QNX versions
documented ?
All this are more or less oddnesses one can overcome but starting with QNX 7 the hook
does not seem to be called at all. After several hours of investigation we changed our
implementation to hook with pfil_head_get(PFIL_TYPE_IFT, IFT_ETHER) instead of the interface
specific implementation PFIL_TYPE_IFNET mentioned above and this is still working on
QNX 7 with the obvious drawback that we have to handle all mbufs which are not for our
interface, too.
Now we got curious and analyzed the ether_input() routine where both hooks are handled.
Compared to earlier implementations again the FIB support seems to make the difference.
In previous QNX versions the hooks get called unconditionally but now a call to
if_get_next_fib() is performed before a hook is called. The 2nd parameter of this
call is a so called start_fib which is initialized to -1 before the call to the hooks
which are attached with PFIL_TYPE_IFT. The if_get_next_fib() is called again before
the hooks attached with PFIL_TYPE_IFNET are called but this time the start_fib is not
reset to -1 again but has the value returned from the previous call (which is 16). This causes
the call to return with 17 and to skip the execution of the PFIL_TYPE_IFNET hooks.
3 . My 3rd an most important question is if you have ever tested the interface specific
hooks attached with PFIL_TYPE_IFNET on QNX 7 and if they run in any of your lsm-xxx.so
protocol drivers is there anything special to do (with respect to FIBs ???) to make
our implementation work in the same way as on 6.x.
Unfortunately we have no kernel code insight so all the results above are based on the
analysis of machine code level debugging sessions.
Best regards,
Oliver
|
|
|