Usage of M_PREPEND() function in netgraph processing


New Member

Messages: 5


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,