# Usage of M_PREPEND() function in netgraph processing



## PKraszewski (May 9, 2021)

Hello!

I'm in the process of writing a netgraph node specific to my project, sitting between ethernet node on the left and bunch of udp/sctp nodes on the right (sorta really crippled L2 VPN without encryption). It has "`local`" and set of `peer0`..`peer15` hooks.

The job of the node with flow `local`->`peerX` is simple:

strip Ethernet header
inspect body and pick one of `peerX` hooks to deliver bare payload
The job of the node with flow `peerX`-> `local` is even simpler:

filter-out unexpected packages
prepend a fixed Ethernet header
deliver the expanded packet to `local` hook
I'm basing the code roughly on `ng_vlan` source. While left->right processing is obvious to me (I can use `m_adj(m, 14);` to move beginning of frame forward by 14 bytes), I don't quite follow the right->left path (that is similar to encapsulating of `ng_vlan`).

Ruslan uses `M_PREPEND(m, ETHER_VLAN_ENCAP_LEN, M_NOWAIT);`, but where does it take memory from to move packet pointer down? If there's no free area before the packet, is it copied to a larger buffer? Or (as I browse through `m_prepend(struct mbuf *m, int len, int how)` source), there's sort of linked list of mbufs and system allocates a new mbuf node of the required size and makes it a new head of extended packet? The flow will be significant (_hopefully_ over 1Gbps if other components check out) and I want to avoid unnecessary copying as much as possible.

Also I'd be quite happy with a single `peer` hook, if I were somehow able to control the IP and PORT of outgoing packets via a signgle UDP socket (that is netgraph equivalent of `sendto`)

Could some good soul point me to some documents on that? Some in-depth guide on mbufs would be helpful, too.

Best regards,


----------

