ntop / PF_RING

High-speed packet processing framework
http://www.ntop.org
GNU Lesser General Public License v2.1
2.64k stars 351 forks source link

Working around loss of kernel stack when ZC is active #898

Closed mzpqnxow closed 7 months ago

mzpqnxow commented 7 months ago

Hello,

This may be more appropriate for a mailing list or other forum, if so please let me know

I have a few servers that only have a single physical network link. For these, while my zc application runs, I lose the ability to manage it via SSH, as expected

Unfortunately, I do NOT have any options in terms of adding another network link for these specific systems. Normally I just add a cheap 100Mbps management link, but I'm constrained here

So, I'm wondering if there are any good workarounds for the fact that, once in ZC mode, all networking is lost to/from the system, because the kernel stack no longer handles the traffic. I would like to be able to use ssh while the application is running in ZC mode

For context, my zc application does high speed transmit, lots of small TCP packets, <100 bytes each. I use only a single source port, to reserve the right to steer on either side if ever needed. The receive volume is only ~5% of that amount.

Are there any clever options for maintaining the ability to manage the system via SSH while my application is running, in a way that doesn't completely negate the performance that zc is offering?

My ideas thus far:

Any insight or guidance is appreciated. I've read a LOT of documentation over the past couple of years, but it's proven very difficult to conclude anything. I know I'm an edge case, as usual... đŸ˜”

Thanks

cardigliano commented 7 months ago

@mzpqnxow the only way to support this, is to handle host traffic forwarding it to the stack from the application which is running ZC (nScrub for instance is doing this), but this required non-trivial changes to the application.

mzpqnxow commented 7 months ago

@mzpqnxow the only way to support this, is to handle host traffic forwarding it to the stack from the application which is running ZC

Understood, thanks for clarifying

nScrub for instance is doing this), but this required non-trivial changes to the application.

Thanks for the reference. Regardless of whether I end up sinking time into exploring or implementing a solution, I enjoy reading about other applications using ZC for anything other than the "capture packets" use-case, so it's appreciated either way

So at the least, my rx thread would need to also handle packets that are not intended for the application. Those would then need to be pushed into the "stack" module, to get them through to the kernel tcp/ip stack to the SSH daemon, I think. At least for the ingress delivery. I'm not sure how the return traffic would work yet but I have enough to look into it

Even it's not really a solution for my use-case, it would be neat to have a PF_RING ZC equivalent project to the libvma project that Mellanox has on top of Infiniband verbs. I know, it's far from apples to apples, but similar enough

I'm sure you're familiar with IB verbs, but if you're not familiar with libvma- in a nutshell, it's a shim (drop in replacement, really) for the standard high-level socket libc functions that's implemented as a shared library. So it can be "enabled" for any libc-based application, without any changes to the executable, via LD_PRELOAD. Lots of caveats, but it's a great approach. It doesn't help the hip rust & golang crowd though, since they don't link against libc

Anyway, thanks for the sanity check and guidance!

cardigliano commented 7 months ago

Yes, you should use the pf_ring "stack" module to both inject (pfring_send) traffic to the stack and read (pfring_recv) and send to the wire traffic from the stack.

cardigliano commented 7 months ago

And thank you for the libvma references and explanation, I know similar projects and it's really interesting.