To me, the key question still is: Does FastPath require a hard dependency on patched drivers, or can ROS use skb with standard hooks?
`
Yes, of course. That's what we are discussing.
Unfortunately, at the moment, I feel that we (on the outside of MT engineering) lack enough evidence to definitively say one way or the other, and that we can both be looking at the available evidence and yet still reasonably come to the exact opposite conclusion.
For example...
`
Your observations (e.g. counters staying at zero) might also suggest that the FastPath metrics themselves aren’t being reported correctly — rather than FastPath not working at all. The fact that ROS reports FastPath as enabled on x86 even if counters stay at 0 still suggests that the mechanism is present and able to engage.
`
...I do not see your conclusion here as inescapable. I could just as easily argue that Fast Path and Fast Track reporting in ROS is merely an indicator that all of the "soft" requirements have been met (that is, there is no user config -- e.g., firewall filter rules, etc. -- that would stand in the way of it working,
were it actually supported on the hardware itself), and not that it is a definitive sign that Fast-Path-ing is actually happening. The RB850Gx2, which infamously does not support Fast Path, will
also show "ipv4-fast-path-active: yes" or "ipv4-fast-track-active: yes" as long as
these .
conditions are met.
`
Mikrotik’s documentation is infamously vague
`
I will give you that one.

`
But with ROS v7 (now on Linux 5.6.3), full support for L2MTU is present in the kernel via netlink
`
I hadn't heard this / wasn't aware of a new L2MTU support being added to more recent mainline Linux releases, but even if that is true, as far as I can tell from looking at MikroTik's patches to 5.6.3, they don't seem to be making use of whatever new "native" L2MTU support there is. Most of their custom/in-house L2MTU stuff that existed in their 3.3.5 patches appears to have been dropped in place almost verbatim (+ there is some new "MPLSMTU" stuff that is implemented much the same way).
`
it’s more likely just a Mikrotik-defined standard transiver hook, declared something like this:
`
I am admittedly nowhere near a Linux kernel internals expert, even less so on the network stack side. That said, it still seems like more than that is actually going on, though I could be vastly misinterpreting things here (see: previous sentence).
Here is the actual definition of the function under discussion:
`
int (*ndo_fast_path_xmit) (struct net_device *dev, struct fp_buf *fpb);
`
So calls to this are not just passing a standard sk_buff along with the device struct, but rather some other packet buffer (meta?-)structure, which is also (seemingly) brand-new.
Frustratingly, I cannot find the actual definition of this struct ANYWHERE within either MT's patchset, or within a full Linux source tree that the patch has been applied to. It is forwardly declared within the patch, immediately before the beginning of the net_device_ops struct definition, so that the struct type can be referenced as a parameter to be passed to the fast_path_xmit function...
`
struct fp_buf;
struct net_device_ops {
[...]
`
...but that's all she wrote. The actual definition of the struct and its members is nowhere to be found. I mean, I suppose it's possible that this could be getting aliased to sk_buff itself, but we simply don't know!
There are several other Fast Path related structures, whose names all begin with 'fp_', and many of which are also missing definitions, with the notable exception of fp_dev (it appears all of the others are being forward-declared because there are members of fp_dev made of those struct types):
`
struct fp_stuff;
struct fp_dev_pcpu_stats;
struct fp_stats_rcu;
struct fp_dev {
struct fp_stuff *stuff;
int (*xmit)(struct net_device *dev, struct fp_buf *fpb);
struct hlist_node list;
struct fp_dev_pcpu_stats __percpu *stats;
struct fp_stats_rcu *stats_rcu;
u64 sp_rx_packet;
u64 sp_tx_packet;
u64 sp_rx_byte;
u64 sp_tx_byte;
u64 fp_rx_packet;
u64 fp_tx_packet;
u64 fp_rx_byte;
u64 fp_tx_byte;
u64 tx_drop;
};
`
So we see what look like a bunch of stats/counter variables, and an ambiguous "stuff" structure, heh. It also sure looks like that same ndo_fast_path_xmit() function is being pointed at within the fp_dev struct, too, just under a different (shorter) name...
The fp_dev struct gets instantiated within the net_device struct:
`
struct net_device {
[...]
unsigned devid;
struct fp_dev fp;
unsigned long list_bitmap[256 / BITS_PER_LONG];
`
...and yet I cannot find a single place in the whole of the Linux source tree where dev.fp / dev->fp is ever touched or referenced.
There are also a bunch of other Fast Path related functions declared in include/linux/netdevice.h...
`
extern void (*fp_ptype_all_changed)(int);
extern void (*fp_nf_changed)(int, int pf);
extern void (*fp_xfrm_changed)(int);
`
...which are getting exported out of net/core/dev.c. Except that
the actual code for all of these functions is completely missing, too!:
`
void (*ipv4_routing_changed)(void);
void (*fp_ptype_all_changed)(int);
void (*fp_nf_changed)(int, int pf);
void (*fp_xfrm_changed)(int);
EXPORT_SYMBOL(ipv4_routing_changed);
EXPORT_SYMBOL(fp_ptype_all_changed);
EXPORT_SYMBOL(fp_nf_changed);
EXPORT_SYMBOL(fp_xfrm_changed);
`
There are a handful of calls being made to these functions that I can find scattered around, but no backing code. That's all that exists.
Finally, there is one additional function pointer that was added to net_device_ops right below the fast_path_xmit one:
`
int (*ndo_xmit_commit) (struct net_device *dev);
`
I don't actually know that it is Fast Path related, but...probably?
In any case, I cannot find a single implementation of either ndo_fast_path_xmit or ndo_xmit_commit ANYWHERE, either. So either I'm blind as a bat, or MikroTik seemingly left a bunch of applicable code out of its GPL kernel patches.
As an interesting side note, I had a set of kernel patches laying around from a 6.5 release candidate, and ndo_fast_path_xmit actually used to be defined this way:
`
netdev_tx_t (*ndo_fast_path_xmit) (struct net_device *dev, struct net_device *port, void *buf);