The constructor for the type is called. If creation of a new node is allowed, constructor method may allocate any special resources it needs. For nodes that correspond to hardware, this is typically done during the device attach routine. Often a global ASCII name corresponding to the device name is assigned here as well.
Creation of a new hook
The hook is created and tentatively linked to the node, and the node is told about the name that will be used to describe this hook. The node sets up any special data structures it needs, or may reject the connection, based on the name of the hook.
Successful connection of two hooks
After both ends have accepted their hooks, and the links have been made, the nodes get a chance to find out who their peer is across the link, and can then decide to reject the connection. Tear-down is automatic. This is also the time at which a node may decide whether to set a particular hook (or its peer) into the queueing mode.
Destruction of a hook
The node is notified of a broken connection. The node may consider some hooks to be critical to operation and others to be expendable: the disconnection of one hook may be an acceptable event while for another it may effect a total shutdown for the node.
Preshutdown of a node
This method is called before real shutdown, which is discussed below. While in this method, the node is fully operational and can send a "goodbye" message to its peers, or it can exclude itself from the chain and reconnect its peers together, like the ng_tee(4) node type does.
Shutdown of a node
This method allows a node to clean up and to ensure that any actions that need to be performed at this time are taken. The method is called by the generic (i.e., superclass) node destructor which will get rid of the generic components of the node. Some nodes (usually associated with a piece of hardware) may be persistent in that a shutdown breaks all edges and resets the node, but does not remove it. In this case, the shutdown method should not free its resources, but rather, clean up and then call the NG_NODE_REVIVE macro to signal the generic code that the shutdown is aborted. In the case where the shutdown is started by the node itself due to hardware removal or unloading (via ng_rmnode_self), it should set the NGF_REALLY_DIE flag to signal to its own shutdown method that it is not to persist.
A netgraph queueable request item, usually referred to as an item, is received by this function. The item contains a pointer to an .Vt mbuf .
The node is notified on which hook the item has arrived, and can use this information in its processing decision. The receiving node must always NG_FREE_M the .Vt mbuf chain on completion or error, or pass it on to another node (or kernel module) which will then be responsible for freeing it. Similarly, the item must be freed if it is not to be passed on to another node, by using the NG_FREE_ITEM macro. If the item still holds references to .Vt mbufs at the time of freeing then they will also be appropriately freed. Therefore, if there is any chance that the .Vt mbuf will be changed or freed separately from the item, it is very important that it be retrieved using the NGI_GET_M macro that also removes the reference within the item. (Or multiple frees of the same object will occur.)
If it is only required to examine the contents of the .Vt mbufs , then it is possible to use the NGI_M macro to both read and rewrite .Vt mbuf pointer inside the item.
If developer needs to pass any meta information along with the .Vt mbuf chain , he should use mbuf_tags(9) framework. .Bf -symbolic Note that old netgraph specific meta-data format is obsoleted now. .Ef
The receiving node may decide to defer the data by queueing it in the netgraph NETISR system (see below). It achieves this by setting the HK_QUEUE flag in the flags word of the hook on which that data will arrive. The infrastructure will respect that bit and queue the data for delivery at a later time, rather than deliver it directly. A node may decide to set the bit on the peer node, so that its own output packets are queued.
The node may elect to nominate a different receive data function for data received on a particular hook, to simplify coding. It uses the NG_HOOK_SET_RCVDATA hook fn macro to do this. The function receives the same arguments in every way other than it will receive all (and only) packets from that hook.
Receive control message
This method is called when a control message is addressed to the node. As with the received data, an item is received, with a pointer to the control message. The message can be examined using the NGI_MSG macro, or completely extracted from the item using the NGI_GET_MSG which also removes the reference within the item. If the Item still holds a reference to the message when it is freed (using the NG_FREE_ITEM macro), then the message will also be freed appropriately. If the reference has been removed, the node must free the message itself using the NG_FREE_MSG macro. A return address is always supplied, giving the address of the node that originated the message so a reply message can be sent anytime later. The return address is retrieved from the item using the NGI_RETADDR macro and is of type .Vt ng_ID_t . All control messages and replies are allocated with the malloc(9) type M_NETGRAPH_MSG, however it is more convenient to use the NG_MKMESSAGE and NG_MKRESPONSE macros to allocate and fill out a message. Messages must be freed using the NG_FREE_MSG macro.
If the message was delivered via a specific hook, that hook will also be made known, which allows the use of such things as flow-control messages, and status change messages, where the node may want to forward the message out another hook to that on which it arrived.
The node may elect to nominate a different receive message function for messages received on a particular hook, to simplify coding. It uses the NG_HOOK_SET_RCVMSG hook fn macro to do this. The function receives the same arguments in every way other than it will receive all (and only) messages from that hook.
Node authors should always use the following typedef to declare their pointers, and should never actually declare the structure.
.Fd "typedef struct ng_node *node_p;"
The following properties are associated with a node, and can be accessed in the following manner:
Validity
A driver or interrupt routine may want to check whether the node is still valid. It is assumed that the caller holds a reference on the node so it will not have been freed, however it may have been disabled or otherwise shut down. Using the NG_NODE_IS_VALID node macro will return this state. Eventually it should be almost impossible for code to run in an invalid node but at this time that work has not been completed.
Node ID(Vt ng_ID_t)
This property can be retrieved using the macro NG_NODE_ID node.
Node name
Optional globally unique name, NUL terminated string. If there is a value in here, it is the name of the node.
if (NG_NODE_NAME(node)[0] != ’\0’) ...
if (strcmp(NG_NODE_NAME(node), "fred") == 0) ...
A node dependent opaque cookie
Anything of the pointer type can be placed here. The macros NG_NODE_SET_PRIVATE node value and NG_NODE_PRIVATE node set and retrieve this property, respectively.
Number of hooks
The NG_NODE_NUMHOOKS node macro is used to retrieve this value.
Hooks
The node may have a number of hooks. A traversal method is provided to allow all the hooks to be tested for some condition. NG_NODE_FOREACH_HOOK node fn arg rethook where fn is a function that will be called for each hook with the form fn hook arg and returning 0 to terminate the search. If the search is terminated, then rethook will be set to the hook at which the search was terminated.
Vt "struct ng_hook"
Node authors should always use the following typedef to declare their hook pointers.
.Fd "typedef struct ng_hook *hook_p;"
The following properties are associated with a hook, and can be accessed in the following manner:
A hook dependent opaque cookie
Anything of the pointer type can be placed here. The macros NG_HOOK_SET_PRIVATE hook value and NG_HOOK_PRIVATE hook set and retrieve this property, respectively.
An associate node
The macro NG_HOOK_NODE hook finds the associated node.
A peer hook(Vt hook_p)
The other hook in this connected pair. The NG_HOOK_PEER hook macro finds the peer.
References
The NG_HOOK_REF hook and NG_HOOK_UNREF hook macros increment and decrement the hook reference count accordingly. After decrement you should always assume the hook has been freed unless you have another reference still valid.
Override receive functions
The NG_HOOK_SET_RCVDATA hook fn and NG_HOOK_SET_RCVMSG hook fn macros can be used to set override methods that will be used in preference to the generic receive data and receive message functions. To unset these, use the macros to set them to NULL. They will only be used for data and messages received on the hook on which they are set.
The maintenance of the names, reference counts, and linked list of hooks for each node is handled automatically by the netgraph subsystem. Typically a node’s private info contains a back-pointer to the node or hook structure, which counts as a new reference that must be included in the reference count for the node. When the node constructor is called, there is already a reference for this calculated in, so that when the node is destroyed, it should remember to do a NG_NODE_UNREF on the node.
From a hook you can obtain the corresponding node, and from a node, it is possible to traverse all the active hooks.
Indicates the version of the netgraph message protocol itself. The current version is NG_VERSION.
arglen
This is the length of any extra arguments, which begin at data.
flags
Indicates whether this is a command or a response control message.
token
The token is a means by which a sender can match a reply message to the corresponding command message; the reply always has the same token.
typecookie
The corresponding node type’s unique 32-bit value. If a node does not recognize the type cookie it must reject the message by returning EINVAL.
Each type should have an include file that defines the commands, argument format, and cookie for its own messages. The typecookie insures that the same header file was included by both sender and receiver; when an incompatible change in the header file is made, the typecookie must be changed. The de-facto method for generating unique type cookies is to take the seconds from the Epoch at the time the header file is written (i.e., the output of "date-u +%s").
There is a predefined typecookie NGM_GENERIC_COOKIE for the .Vt generic node type, and a corresponding set of generic messages which all nodes understand. The handling of these messages is automatic.
cmd
The identifier for the message command. This is type specific, and is defined in the same header file as the typecookie.
cmdstr
Room for a short human readable version of command (for debugging purposes only).
Connect to another node, using the supplied hook names on either end.
NGM_MKPEER
Construct a node of the given type and then connect to it using the supplied hook names.
NGM_SHUTDOWN
The target node should disconnect from all its neighbours and shut down. Persistent nodes such as those representing physical hardware might not disappear from the node namespace, but only reset themselves. The node must disconnect all of its hooks. This may result in neighbors shutting themselves down, and possibly a cascading shutdown of the entire connected graph.
NGM_NAME
Assign a name to a node. Nodes can exist without having a name, and this is the default for nodes created using the NGM_MKPEER method. Such nodes can only be addressed relatively or by their ID number.
NGM_RMHOOK
Ask the node to break a hook connection to one of its neighbours. Both nodes will have their "disconnect" method invoked. Either node may elect to totally shut down as a result.
NGM_NODEINFO
Asks the target node to describe itself. The four returned fields are the node name (if named), the node type, the node ID and the number of hooks attached. The ID is an internal number unique to that node.
NGM_LISTHOOKS
This returns the information given by NGM_NODEINFO, but in addition includes an array of fields describing each link, and the description for the node at the far end of that link.
NGM_LISTNAMES
This returns an array of node descriptions (as for NGM_NODEINFO) where each entry of the array describes a named node. All named nodes will be described.
NGM_LISTNODES
This is the same as NGM_LISTNAMES except that all nodes are listed regardless of whether they have a name or not.
NGM_LISTTYPES
This returns a list of all currently installed netgraph types.
NGM_TEXT_STATUS
The node may return a text formatted status message. The status information is determined entirely by the node type. It is the only "generic" message that requires any support within the node itself and as such the node may elect to not support this message. The text response must be less than NG_TEXTRESPONSE bytes in length (presently 1024). This can be used to return general status information in human readable form.
NGM_BINARY2ASCII
This message converts a binary control message to its ASCII form. The entire control message to be converted is contained within the arguments field of the NGM_BINARY2ASCII message itself. If successful, the reply will contain the same control message in ASCII form. A node will typically only know how to translate messages that it itself understands, so the target node of the NGM_BINARY2ASCII is often the same node that would actually receive that message.
NGM_ASCII2BINARY
The opposite of NGM_BINARY2ASCII. The entire control message to be converted, in ASCII form, is contained in the arguments section of the NGM_ASCII2BINARY and need only have the flags, cmdstr, and arglen header fields filled in, plus the NUL -terminated string version of the arguments in the arguments field. If successful, the reply contains the binary version of the control message.
The socket type implements two new sockets in the new protocol domain PF_NETGRAPH. The new sockets protocols are NG_DATA and NG_CONTROL, both of type SOCK_DGRAM. Typically one of each is associated with a socket node. When both sockets have closed, the node will shut down. The NG_DATA socket is used for sending and receiving data, while the NG_CONTROL socket is used for sending and receiving control messages. Data and control messages are passed using the sendto(2) and recvfrom(2) system calls, using a .Vt "struct sockaddr_ng" socket address.
HOLE
Responds only to generic messages and is a "black hole" for data. Useful for testing. Always accepts new hooks.
ECHO
Responds only to generic messages and always echoes data back through the hook from which it arrived. Returns any non-generic messages as their own response. Useful for testing. Always accepts new hooks.
TEE
This node is useful for "snooping". It has 4 hooks: left, right, left2right, and right2left. Data entering from the right is passed to the left and duplicated on right2left, and data entering from the left is passed to the right and duplicated on left2right. Data entering from left2right is sent to the right and data from right2left to left.
RFC1490 MUX
Encapsulates/de-encapsulates frames encoded according to RFC 1490. Has a hook for the encapsulated packets (downstream) and one hook for each protocol (i.e., IP, PPP, etc.).
FRAME RELAY MUX
Encapsulates/de-encapsulates Frame Relay frames. Has a hook for the encapsulated packets (downstream) and one hook for each DLCI.
FRAME RELAY LMI
Automatically handles frame relay "LMI" (link management interface) operations and packets. Automatically probes and detects which of several LMI standards is in use at the exchange.
TTY
This node is also a line discipline. It simply converts between .Vt mbuf frames and sequential serial data, allowing a TTY to appear as a netgraph node. It has a programmable "hotkey" character.
ASYNC
This node encapsulates and de-encapsulates asynchronous frames according to RFC 1662. This is used in conjunction with the TTY node type for supporting PPP links over asynchronous serial lines.
ETHERNET
This node is attached to every Ethernet interface in the system. It allows capturing raw Ethernet frames from the network, as well as sending frames out of the interface.
INTERFACE
This node is also a system networking interface. It has hooks representing each protocol family (IP, AppleTalk, IPX, etc.) and appears in the output of ifconfig(8). The interfaces are named "ng0", "ng1", etc.
ONE2MANY
This node implements a simple round-robin multiplexer. It can be used for example to make several LAN ports act together to get a higher speed link between two machines.
Various PPP related nodes
There is a full multilink PPP implementation that runs in netgraph. The net/mpd port can use these modules to make a very low latency high capacity PPP system. It also supports PPTP VPNs using the PPTP node.
PPPOE
A server and client side implementation of PPPoE. Used in conjunction with either ppp(8) or the net/mpd port.
BRIDGE
This node, together with the Ethernet nodes, allows a very flexible bridging system to be implemented.
KSOCKET
This intriguing node looks like a socket to the system but diverts all data to and from the netgraph system for further processing. This allows such things as UDP tunnels to be almost trivially implemented from the command line.