1999-10-21 09:06:11 +00:00
|
|
|
.\" Copyright (c) 1996-1999 Whistle Communications, Inc.
|
|
|
|
.\" All rights reserved.
|
|
|
|
.\"
|
|
|
|
.\" Subject to the following obligations and disclaimer of warranty, use and
|
|
|
|
.\" redistribution of this software, in source or object code forms, with or
|
|
|
|
.\" without modifications are expressly permitted by Whistle Communications;
|
|
|
|
.\" provided, however, that:
|
|
|
|
.\" 1. Any and all reproductions of the source or object code must include the
|
|
|
|
.\" copyright notice above and the following disclaimer of warranties; and
|
|
|
|
.\" 2. No rights are granted, in any manner or form, to use Whistle
|
|
|
|
.\" Communications, Inc. trademarks, including the mark "WHISTLE
|
|
|
|
.\" COMMUNICATIONS" on advertising, endorsements, or otherwise except as
|
|
|
|
.\" such appears in the above copyright notice or in the software.
|
|
|
|
.\"
|
|
|
|
.\" THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
|
|
|
|
.\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
|
|
|
|
.\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
|
|
|
|
.\" INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
|
|
|
|
.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
|
|
|
.\" WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
|
|
|
|
.\" REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
|
|
|
|
.\" SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
|
|
|
|
.\" IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
|
|
|
|
.\" RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
|
|
|
|
.\" WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
|
|
|
.\" PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
|
|
.\" SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
|
|
|
|
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
.\" THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
|
|
|
|
.\" OF SUCH DAMAGE.
|
|
|
|
.\"
|
|
|
|
.\" Authors: Julian Elischer <julian@whistle.com>
|
|
|
|
.\" Archie Cobbs <archie@whistle.com>
|
|
|
|
.\"
|
|
|
|
.\" $FreeBSD$
|
|
|
|
.\" $Whistle: netgraph.4,v 1.7 1999/01/28 23:54:52 julian Exp $
|
|
|
|
.\"
|
|
|
|
.Dd January 19, 1999
|
|
|
|
.Dt NETGRAPH 4
|
|
|
|
.Os FreeBSD
|
|
|
|
.Sh NAME
|
|
|
|
.Nm netgraph
|
|
|
|
.Nd graph based kernel networking subsystem
|
|
|
|
.Sh DESCRIPTION
|
|
|
|
The
|
|
|
|
.Nm
|
|
|
|
system provides a uniform and modular system for the implementation
|
|
|
|
of kernel objects which perform various networking functions. The objects,
|
|
|
|
known as
|
|
|
|
.Em nodes ,
|
|
|
|
can be arranged into arbitrarily complicated graphs. Nodes have
|
|
|
|
.Em hooks
|
|
|
|
which are used to connect two nodes together, forming the edges in the graph.
|
|
|
|
Nodes communicate along the edges to process data, implement protocols, etc.
|
|
|
|
.Pp
|
|
|
|
The aim of
|
|
|
|
.Nm
|
|
|
|
is to supplement rather than replace the existing kernel networking
|
|
|
|
infrastructure. It provides:
|
|
|
|
.Pp
|
|
|
|
.Bl -bullet -compact -offset 2n
|
|
|
|
.It
|
|
|
|
A flexible way of combining protocol and link level drivers
|
|
|
|
.It
|
|
|
|
A modular way to implement new protocols
|
|
|
|
.It
|
|
|
|
A common framework for kernel entities to inter-communicate
|
|
|
|
.It
|
|
|
|
A reasonably fast, kernel-based implementation
|
|
|
|
.El
|
|
|
|
.Sh Nodes and Types
|
|
|
|
The most fundamental concept in
|
|
|
|
.Nm
|
|
|
|
is that of a
|
|
|
|
.Em node .
|
|
|
|
All nodes implement a number of predefined methods which allow them
|
|
|
|
to interact with other nodes in a well defined manner.
|
|
|
|
.Pp
|
|
|
|
Each node has a
|
|
|
|
.Em type ,
|
|
|
|
which is a static property of the node determined at node creation time.
|
|
|
|
A node's type is described by a unique ASCII type name.
|
|
|
|
The type implies what the node does and how it may be connected
|
|
|
|
to other nodes.
|
|
|
|
.Pp
|
|
|
|
In object-oriented language, types are classes and nodes are instances
|
|
|
|
of their respective class. All node types are subclasses of the generic node
|
|
|
|
type, and hence inherit certain common functionality and capabilities
|
|
|
|
(e.g., the ability to have an ASCII name).
|
|
|
|
.Pp
|
|
|
|
Nodes may be assigned a globally unique ASCII name which can be
|
|
|
|
used to refer to the node.
|
|
|
|
The name must not contain the characters ``.'' or ``:'' and is limited to
|
|
|
|
.Dv "NG_NODELEN + 1"
|
|
|
|
characters (including NUL byte).
|
|
|
|
.Pp
|
|
|
|
Each node instance has a unique
|
|
|
|
.Em ID number
|
|
|
|
which is expressed as a 32-bit hex value. This value may be used to
|
|
|
|
refer to a node when there is no ASCII name assigned to it.
|
|
|
|
.Sh Hooks
|
|
|
|
Nodes are connected to other nodes by connecting a pair of
|
|
|
|
.Em hooks ,
|
|
|
|
one from each node. Data flows bidirectionally between nodes along
|
|
|
|
connected pairs of hooks. A node may have as many hooks as it
|
|
|
|
needs, and may assign whatever meaning it wants to a hook.
|
|
|
|
.Pp
|
|
|
|
Hooks have these properties:
|
|
|
|
.Pp
|
|
|
|
.Bl -bullet -compact -offset 2n
|
|
|
|
.It
|
|
|
|
A hook has an ASCII name which is unique among all hooks
|
|
|
|
on that node (other hooks on other nodes may have the same name).
|
|
|
|
The name must not contain a ``.'' or a ``:'' and is
|
|
|
|
limited to
|
|
|
|
.Dv "NG_HOOKLEN + 1"
|
|
|
|
characters (including NUL byte).
|
|
|
|
.It
|
|
|
|
A hook is always connected to another hook. That is, hooks are
|
|
|
|
created at the time they are connected, and breaking an edge by
|
|
|
|
removing either hook destroys both hooks.
|
|
|
|
.El
|
|
|
|
.Pp
|
|
|
|
A node may decide to assign special meaning to some hooks.
|
|
|
|
For example, connecting to the hook named ``debug'' might trigger
|
|
|
|
the node to start sending debugging information to that hook.
|
|
|
|
.Sh Data Flow
|
|
|
|
Two types of information flow between nodes: data messages and
|
|
|
|
control messages. Data messages are passed in mbuf chains along the edges
|
|
|
|
in the graph, one edge at a time. The first mbuf in a chain must have the
|
|
|
|
.Dv M_PKTHDR
|
|
|
|
flag set. Each node decides how to handle data coming in on its hooks.
|
|
|
|
.Pp
|
|
|
|
Control messages are type-specific structures sent from one node directly
|
|
|
|
to an arbitrary other node. There are two ways to address such a message. If
|
|
|
|
there is a sequence of edges connecting the two nodes, the message
|
|
|
|
may be ``source routed'' by specifying the corresponding sequence
|
|
|
|
of hooks as the destination address for the message (relative
|
|
|
|
addressing). Otherwise, the recipient node global ASCII name
|
|
|
|
(or equivalent ID based name) is used as the destination address
|
|
|
|
for the message (absolute addressing). The two types of addressing
|
|
|
|
may be combined, by specifying an absolute start node and a sequence
|
|
|
|
of hooks.
|
|
|
|
.Pp
|
|
|
|
Messages often represent commands that are followed by a reply message
|
|
|
|
in the reverse direction. To facilitate this, the recipient of a
|
|
|
|
control message is supplied with a ``return address'' that is suitable
|
|
|
|
for addressing a reply.
|
|
|
|
.Pp
|
|
|
|
Each control message contains a 32 bit value called a
|
|
|
|
.Em typecookie
|
|
|
|
indicating the type of the message, i.e., how to interpret it.
|
|
|
|
Typically each type defines a unique typecookie for the messages
|
|
|
|
that it understands. However, a node may choose to recognize and
|
|
|
|
implement more than one type of message.
|
|
|
|
.Sh Netgraph is Functional
|
|
|
|
In order to minimize latency, most
|
|
|
|
.Nm netgraph
|
|
|
|
operations are functional.
|
|
|
|
That is, data and control messages are delivered by making function
|
|
|
|
calls rather than by using queues and mailboxes. For example, if node
|
|
|
|
A wishes to send a data mbuf to neighboring node B, it calls the
|
|
|
|
generic
|
|
|
|
.Nm
|
|
|
|
data delivery function. This function in turn locates
|
|
|
|
node B and calls B's ``receive data'' method. While this mode of operation
|
|
|
|
results in good performance, it has a few implications for node
|
|
|
|
developers:
|
|
|
|
.Pp
|
|
|
|
.Bl -bullet -compact -offset 2n
|
|
|
|
.It
|
|
|
|
Whenever a node delivers a data or control message, the node
|
|
|
|
may need to allow for the possibility of receiving a returning message
|
|
|
|
before the original delivery function call returns.
|
|
|
|
.It
|
|
|
|
Netgraph nodes and support routines generally run at
|
|
|
|
.Dv "splnet()" .
|
|
|
|
However, some nodes may want to send data and control messages
|
|
|
|
from a different priority level. Netgraph supplies queueing routines which
|
|
|
|
utilize the NETISR system to move message delivery to
|
|
|
|
.Dv "splnet()" .
|
|
|
|
Note that messages are always received at
|
|
|
|
.Dv "splnet()" .
|
|
|
|
.It
|
|
|
|
It's possible for an infinite loop to occur if the graph contains cycles.
|
|
|
|
.El
|
|
|
|
.Pp
|
|
|
|
So far, these issues have not proven problematical in practice.
|
|
|
|
.Sh Interaction With Other Parts of the Kernel
|
|
|
|
A node may have a hidden interaction with other components of the
|
|
|
|
kernel outside of the
|
|
|
|
.Nm
|
|
|
|
subsystem, such as device hardware,
|
|
|
|
kernel protocol stacks, etc. In fact, one of the benefits of
|
|
|
|
.Nm
|
|
|
|
is the ability to join disparate kernel networking entities together in a
|
|
|
|
consistent communication framework.
|
|
|
|
.Pp
|
|
|
|
An example is the node type
|
|
|
|
.Em socket
|
|
|
|
which is both a netgraph node and a
|
|
|
|
.Xr socket 2
|
|
|
|
BSD socket in the protocol family
|
|
|
|
.Dv PF_NETGRAPH .
|
|
|
|
Socket nodes allow user processes to participate in
|
|
|
|
.Nm netgraph .
|
|
|
|
Other nodes communicate with socket nodes using the usual methods, and the
|
|
|
|
node hides the fact that it is also passing information to and from a
|
|
|
|
cooperating user process.
|
|
|
|
.Pp
|
|
|
|
Another example is a device driver that presents
|
|
|
|
a node interface to the hardware.
|
|
|
|
.Sh Node Methods
|
|
|
|
Nodes are notified of the following actions via function calls
|
|
|
|
to the following node methods (all at
|
|
|
|
.Dv "splnet()" )
|
|
|
|
and may accept or reject that action (by returning the appropriate
|
|
|
|
error code):
|
|
|
|
.Bl -tag -width xxx
|
|
|
|
.It Creation of a new node
|
|
|
|
The constructor for the type is called. If creation of a new node is
|
|
|
|
allowed, the constructor must call the generic node creation
|
|
|
|
function (in object-oriented terms, the superclass constructor)
|
|
|
|
and then 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.
|
|
|
|
.It 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.
|
|
|
|
.It 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.
|
|
|
|
.It 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.
|
|
|
|
.It 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 must call the generic (i.e., superclass)
|
|
|
|
node destructor to get rid of the generic components of the node.
|
|
|
|
Some nodes (usually associated with a piece of hardware) may be
|
|
|
|
.Em persistent
|
|
|
|
in that a shutdown breaks all edges and resets the node,
|
|
|
|
but doesn't remove it, in which case the generic destructor is not called.
|
|
|
|
.El
|
|
|
|
.Sh Sending and Receiving Data
|
|
|
|
Three other methods are also supported by all nodes:
|
|
|
|
.Bl -tag -width xxx
|
|
|
|
.It Receive data message
|
|
|
|
An mbuf chain is passed to the node.
|
|
|
|
The node is notified on which hook the data arrived,
|
|
|
|
and can use this information in its processing decision.
|
|
|
|
The node must must always
|
|
|
|
.Dv m_freem()
|
|
|
|
the mbuf chain on completion or error, or pass it on to another node
|
|
|
|
(or kernel module) which will then be responsible for freeing it.
|
|
|
|
.Pp
|
|
|
|
In addition to the mbuf chain itself there is also a pointer to a
|
|
|
|
structure describing meta-data about the message
|
|
|
|
(e.g. priority information). This pointer may be
|
|
|
|
.Dv NULL
|
|
|
|
if there is no additional information. The format for this information is
|
|
|
|
described in
|
|
|
|
.Dv netgraph.h .
|
|
|
|
The memory for meta-data must allocated via
|
|
|
|
.Dv malloc()
|
|
|
|
with type
|
|
|
|
.Dv M_NETGRAPH .
|
|
|
|
As with the data itself, it is the receiver's responsibility to
|
|
|
|
.Dv free()
|
|
|
|
the meta-data. If the mbuf chain is freed the meta-data must
|
|
|
|
be freed at the same time. If the meta-data is freed but the
|
|
|
|
real data on is passed on, then a
|
|
|
|
.Dv NULL
|
|
|
|
pointer must be substituted.
|
|
|
|
.Pp
|
|
|
|
The receiving node may decide to defer the data by queueing it in the
|
|
|
|
.Nm
|
|
|
|
NETISR system (see below).
|
|
|
|
.Pp
|
|
|
|
The structure and use of meta-data is still experimental, but is presently used in
|
|
|
|
frame-relay to indicate that management packets should be queued for transmission
|
|
|
|
at a higher priority than data packets. This is required for
|
|
|
|
conformance with Frame Relay standards.
|
|
|
|
.Pp
|
|
|
|
.It Receive queued data message
|
|
|
|
Usually this will be the same function as
|
|
|
|
.Em Receive data message.
|
|
|
|
This is the entry point called when a data message is being handed to
|
|
|
|
the node after having been queued in the NETISR system.
|
|
|
|
This allows a node to decide in the
|
|
|
|
.Em Receive data message
|
1999-10-30 20:30:19 +00:00
|
|
|
method that a message should be deferred and queued,
|
1999-10-21 09:06:11 +00:00
|
|
|
and be sure that when it is processed from the queue,
|
|
|
|
it will not be queued again.
|
|
|
|
.It Receive control message
|
|
|
|
This method is called when a control message is addressed to the node.
|
|
|
|
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.
|
|
|
|
.Pp
|
|
|
|
It is possible for a synchronous reply to be made, and in fact this
|
|
|
|
is more common in practice.
|
|
|
|
This is done by setting a pointer (supplied as an extra function parameter)
|
|
|
|
to point to the reply.
|
|
|
|
Then when the control message delivery function returns,
|
|
|
|
the caller can check if this pointer has been made non-NULL,
|
|
|
|
and if so then it points to the reply message allocated via
|
|
|
|
.Dv malloc()
|
|
|
|
and containing the synchronous response. In both directions,
|
|
|
|
(request and response) it is up to the
|
|
|
|
receiver of that message to
|
|
|
|
.Dv free()
|
|
|
|
the control message buffer. All control messages and replies are
|
|
|
|
allocated with
|
|
|
|
.Dv malloc()
|
|
|
|
type
|
|
|
|
.Dv M_NETGRAPH .
|
|
|
|
.El
|
|
|
|
.Pp
|
|
|
|
Much use has been made of reference counts, so that nodes being
|
|
|
|
free'd of all references are automatically freed, and this behaviour
|
|
|
|
has been tested and debugged to present a consistent and trustworthy
|
|
|
|
framework for the ``type module'' writer to use.
|
|
|
|
.Sh Addressing
|
|
|
|
The
|
|
|
|
.Nm
|
|
|
|
framework provides an unambiguous and simple to use method of specifically
|
|
|
|
addressing any single node in the graph. The naming of a node is
|
|
|
|
independent of its type, in that another node, or external component
|
|
|
|
need not know anything about the node's type in order to address it so as
|
|
|
|
to send it a generic message type. Node and hook names should be
|
|
|
|
chosen so as to make addresses meaningful.
|
|
|
|
.Pp
|
|
|
|
Addresses are either absolute or relative. An absolute address begins
|
|
|
|
with a node name, (or ID), followed by a colon, followed by a sequence of hook
|
|
|
|
names separated by periods. This addresses the node reached by starting
|
|
|
|
at the named node and following the specified sequence of hooks.
|
|
|
|
A relative address includes only the sequence of hook names, implicitly
|
|
|
|
starting hook traversal at the local node.
|
|
|
|
.Pp
|
|
|
|
There are a couple of special possibilities for the node name.
|
1999-10-30 20:30:19 +00:00
|
|
|
The name ``.'' (referred to as ``.:'') always refers to the local node.
|
1999-10-21 09:06:11 +00:00
|
|
|
Also, nodes that have no global name may be addressed by their ID numbers,
|
|
|
|
by enclosing the hex representation of the ID number within square brackets.
|
|
|
|
Here are some examples of valid netgraph addresses:
|
|
|
|
.Bd -literal -offset 4n -compact
|
|
|
|
|
|
|
|
.:
|
|
|
|
foo:
|
|
|
|
.:hook1
|
|
|
|
foo:hook1.hook2
|
|
|
|
[f057cd80]:hook1
|
|
|
|
.Ed
|
|
|
|
.Pp
|
|
|
|
Consider the following set of nodes might be created for a site with
|
|
|
|
a single physical frame relay line having two active logical DLCI channels,
|
|
|
|
with RFC-1490 frames on DLCI 16 and PPP frames over DLCI 20:
|
|
|
|
.Pp
|
|
|
|
.Bd -literal
|
|
|
|
[type SYNC ] [type FRAME] [type RFC1490]
|
|
|
|
[ "Frame1" ](uplink)<-->(data)[<un-named>](dlci16)<-->(mux)[<un-named> ]
|
|
|
|
[ A ] [ B ](dlci20)<---+ [ C ]
|
|
|
|
|
|
|
|
|
| [ type PPP ]
|
|
|
|
+>(mux)[<un-named>]
|
|
|
|
[ D ]
|
|
|
|
.Ed
|
|
|
|
.Pp
|
|
|
|
One could always send a control message to node C from anywhere
|
|
|
|
by using the name
|
|
|
|
.Em "Frame1:uplink.dlci16" .
|
|
|
|
Similarly,
|
|
|
|
.Em "Frame1:uplink.dlci20"
|
|
|
|
could reliably be used to reach node D, and node A could refer
|
|
|
|
to node B as
|
|
|
|
.Em ".:uplink" ,
|
|
|
|
or simply
|
|
|
|
.Em "uplink" .
|
|
|
|
Conversely, B can refer to A as
|
|
|
|
.Em "data" .
|
|
|
|
The address
|
|
|
|
.Em "mux.data"
|
|
|
|
could be used by both nodes C and D to address a message to node A.
|
|
|
|
.Pp
|
|
|
|
Note that this is only for
|
|
|
|
.Em control messages .
|
|
|
|
Data messages are routed one hop at a time, by specifying the departing
|
|
|
|
hook, with each node making the next routing decision. So when B
|
|
|
|
receives a frame on hook
|
|
|
|
.Em data
|
|
|
|
it decodes the frame relay header to determine the DLCI,
|
|
|
|
and then forwards the unwrapped frame to either C or D.
|
|
|
|
.Pp
|
|
|
|
A similar graph might be used to represent multi-link PPP running
|
|
|
|
over an ISDN line:
|
|
|
|
.Pp
|
|
|
|
.Bd -literal
|
|
|
|
[ type BRI ](B1)<--->(link1)[ type MPP ]
|
|
|
|
[ "ISDN1" ](B2)<--->(link2)[ (no name) ]
|
|
|
|
[ ](D) <-+
|
|
|
|
|
|
|
|
|
+----------------+
|
|
|
|
|
|
|
|
|
+->(switch)[ type Q.921 ](term1)<---->(datalink)[ type Q.931 ]
|
|
|
|
[ (no name) ] [ (no name) ]
|
|
|
|
.Ed
|
|
|
|
.Sh Netgraph Structures
|
|
|
|
Interesting members of the node and hook structures are shown below:
|
|
|
|
.Bd -literal
|
|
|
|
struct ng_node {
|
|
|
|
char *name; /* Optional globally unique name */
|
|
|
|
void *private; /* Node implementation private info */
|
|
|
|
struct ng_type *type; /* The type of this node */
|
|
|
|
int refs; /* Number of references to this struct */
|
|
|
|
int numhooks; /* Number of connected hooks */
|
|
|
|
hook_p hooks; /* Linked list of (connected) hooks */
|
|
|
|
};
|
|
|
|
typedef struct ng_node *node_p;
|
|
|
|
|
|
|
|
struct ng_hook {
|
|
|
|
char *name; /* This node's name for this hook */
|
|
|
|
void *private; /* Node implementation private info */
|
|
|
|
int refs; /* Number of references to this struct */
|
|
|
|
struct ng_node *node; /* The node this hook is attached to */
|
|
|
|
struct ng_hook *peer; /* The other hook in this connected pair */
|
|
|
|
struct ng_hook *next; /* Next in list of hooks for this node */
|
|
|
|
};
|
|
|
|
typedef struct ng_hook *hook_p;
|
|
|
|
.Ed
|
|
|
|
.Pp
|
|
|
|
The maintenance of the name pointers, reference counts, and linked list
|
|
|
|
of hooks for each node is handled automatically by the
|
|
|
|
.Nm
|
|
|
|
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 registered by
|
|
|
|
incrementing
|
|
|
|
.Dv "node->refs" .
|
|
|
|
.Pp
|
|
|
|
From a hook you can obtain the corresponding node, and from
|
|
|
|
a node the list of all active hooks.
|
|
|
|
.Pp
|
|
|
|
Node types are described by this structure:
|
|
|
|
.Bd -literal
|
|
|
|
struct ng_type {
|
|
|
|
u_int32_t version; /* Must equal NG_VERSION */
|
|
|
|
const char *name; /* Unique type name */
|
|
|
|
|
|
|
|
/* Module event handler */
|
|
|
|
modeventhand_t mod_event; /* Handle load/unload (optional) */
|
|
|
|
|
|
|
|
/* Constructor */
|
|
|
|
int (*constructor)(node_p *node); /* Create a new node */
|
|
|
|
|
|
|
|
/** Methods using the node **/
|
|
|
|
int (*rcvmsg)(node_p node, /* Receive control message */
|
|
|
|
struct ng_mesg *msg, /* The message */
|
|
|
|
const char *retaddr, /* Return address */
|
|
|
|
struct ng_mesg **resp); /* Synchronous response */
|
|
|
|
int (*shutdown)(node_p node); /* Shutdown this node */
|
|
|
|
int (*newhook)(node_p node, /* create a new hook */
|
|
|
|
hook_p hook, /* Pre-allocated struct */
|
|
|
|
const char *name); /* Name for new hook */
|
|
|
|
|
|
|
|
/** Methods using the hook **/
|
|
|
|
int (*connect)(hook_p hook); /* Confirm new hook attachment */
|
|
|
|
int (*rcvdata)(hook_p hook, /* Receive data on a hook */
|
|
|
|
struct mbuf *m, /* The data in an mbuf */
|
|
|
|
meta_p meta); /* Meta-data, if any */
|
|
|
|
int (*disconnect)(hook_p hook); /* Notify disconnection of hook */
|
|
|
|
};
|
|
|
|
.Ed
|
|
|
|
.Pp
|
|
|
|
Control messages have the following structure:
|
|
|
|
.Bd -literal
|
|
|
|
#define NG_CMDSTRLEN 15 /* Max command string (16 with null) */
|
|
|
|
|
|
|
|
struct ng_mesg {
|
|
|
|
struct ng_msghdr {
|
|
|
|
u_char version; /* Must equal NG_VERSION */
|
|
|
|
u_char spare; /* Pad to 2 bytes */
|
|
|
|
u_short arglen; /* Length of cmd/resp data */
|
|
|
|
u_long flags; /* Message status flags */
|
|
|
|
u_long token; /* Reply should have the same token */
|
|
|
|
u_long typecookie; /* Node type understanding this message */
|
|
|
|
u_long cmd; /* Command identifier */
|
|
|
|
u_char cmdstr[NG_CMDSTRLEN+1]; /* Cmd string (for debug) */
|
|
|
|
} header;
|
|
|
|
char data[0]; /* Start of cmd/resp data */
|
|
|
|
};
|
|
|
|
|
|
|
|
#define NG_VERSION 1 /* Netgraph version */
|
|
|
|
#define NGF_ORIG 0x0000 /* Command */
|
|
|
|
#define NGF_RESP 0x0001 /* Response */
|
|
|
|
.Ed
|
|
|
|
.Pp
|
|
|
|
Control messages have the fixed header shown above, followed by a
|
|
|
|
variable length data section which depends on the type cookie
|
|
|
|
and the command. Each field is explained below:
|
|
|
|
.Bl -tag -width xxx
|
|
|
|
.It Dv version
|
|
|
|
Indicates the version of netgraph itself. The current version is
|
|
|
|
.Dv NG_VERSION .
|
|
|
|
.It Dv arglen
|
|
|
|
This is the length of any extra arguments, which begin at
|
|
|
|
.Dv data .
|
|
|
|
.It Dv flags
|
|
|
|
Indicates whether this is a command or a response control message.
|
|
|
|
.It Dv token
|
|
|
|
The
|
|
|
|
.Dv 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.
|
|
|
|
.Pp
|
|
|
|
.It Dv typecookie
|
|
|
|
The corresponding node type's unique 32-bit value.
|
|
|
|
If a node doesn't recognize the type cookie it must reject the message
|
|
|
|
by returning
|
|
|
|
.Er EINVAL .
|
|
|
|
.Pp
|
|
|
|
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
|
|
|
|
.Em 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
|
|
|
|
.Dv "date -u +'%s'" ")."
|
|
|
|
.Pp
|
|
|
|
There is a predefined typecookie
|
|
|
|
.Dv NGM_GENERIC_COOKIE
|
|
|
|
for the ``generic'' node type, and
|
|
|
|
a corresponding set of generic messages which all nodes understand.
|
|
|
|
The handling of these messages is automatic.
|
|
|
|
.It Dv command
|
|
|
|
The identifier for the message command. This is type specific,
|
|
|
|
and is defined in the same header file as the typecookie.
|
|
|
|
.It Dv cmdstr
|
|
|
|
Room for a short human readable version of ``command'' (for debugging
|
|
|
|
purposes only).
|
|
|
|
.El
|
|
|
|
.Pp
|
|
|
|
Some modules may choose to implement messages from more than one
|
|
|
|
of the header files and thus recognize more than one type cookie.
|
|
|
|
.Sh Generic Control Messages
|
|
|
|
There are a number of standard predefined messages that will work
|
|
|
|
for any node, as they are supported directly by the framework itself.
|
|
|
|
These are defined in
|
|
|
|
.Dv ng_message.h
|
|
|
|
along with the basic layout of messages and other similar information.
|
|
|
|
.Bl -tag -width xxx
|
|
|
|
.It Dv NGM_CONNECT
|
|
|
|
Connect to another node, using the supplied hook names on either end.
|
|
|
|
.It Dv NGM_MKPEER
|
|
|
|
Construct a node of the given type and then connect to it using the
|
|
|
|
supplied hook names.
|
|
|
|
.It Dv NGM_SHUTDOWN
|
|
|
|
The target node should disconnect from all its neighbours and shut down.
|
|
|
|
Persistent nodes such as those representing physical hardware
|
1999-10-30 20:30:19 +00:00
|
|
|
might not disappear from the node namespace, but only reset themselves.
|
1999-10-21 09:06:11 +00:00
|
|
|
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.
|
|
|
|
.It Dv 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
|
|
|
|
.Dv NGM_MKPEER
|
|
|
|
method. Such nodes can only be addressed relatively or by their ID number.
|
|
|
|
.It Dv 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.
|
|
|
|
.It Dv 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.
|
|
|
|
.It Dv NGM_LISTHOOKS
|
|
|
|
This returns the information given by
|
|
|
|
.Dv NGM_NODEINFO ,
|
|
|
|
but in addition
|
1999-10-30 20:30:19 +00:00
|
|
|
includes an array of fields describing each link, and the description for
|
1999-10-21 09:06:11 +00:00
|
|
|
the node at the far end of that link.
|
|
|
|
.It Dv NGM_LISTNAMES
|
|
|
|
This returns an array of node descriptions (as for
|
|
|
|
.Dv NGM_NODEINFO ")"
|
|
|
|
where each entry of the array describes a named node.
|
|
|
|
All named nodes will be described.
|
|
|
|
.It Dv NGM_LISTNODES
|
|
|
|
This is the same as
|
|
|
|
.Dv NGM_LISTNAMES
|
|
|
|
except that all nodes are listed regardless of whether they have a name or not.
|
|
|
|
.It Dv NGM_LISTTYPES
|
|
|
|
This returns a list of all currently installed netgraph types.
|
|
|
|
.It Dv 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
|
|
|
|
.Dv NG_TEXTRESPONSE
|
|
|
|
bytes in length (presently 1024). This can be used to return general
|
|
|
|
status information in human readable form.
|
|
|
|
.El
|
|
|
|
.Sh Metadata
|
|
|
|
Data moving through the
|
|
|
|
.Nm
|
|
|
|
system can be accompanied by meta-data that describes some
|
|
|
|
aspect of that data. The form of the meta-data is a fixed header,
|
|
|
|
which contains enough information for most uses, and can optionally
|
1999-10-30 20:30:19 +00:00
|
|
|
be supplemented by trailing
|
1999-10-21 09:06:11 +00:00
|
|
|
.Em option
|
|
|
|
structures, which contain a
|
|
|
|
.Em cookie
|
|
|
|
(see the section on control messages), an identifier, a length and optional
|
|
|
|
data. If a node does not recognize the cookie associated with an option,
|
|
|
|
it should ignore that option.
|
|
|
|
.Pp
|
|
|
|
Meta data might include such things as priority, discard eligibility,
|
|
|
|
or special processing requirements. It might also mark a packet for
|
|
|
|
debug status, etc. The use of meta-data is still experimental.
|
|
|
|
.Sh INITIALIZATION
|
|
|
|
The base
|
|
|
|
.Nm
|
|
|
|
code may either be statically compiled
|
|
|
|
into the kernel or else loaded dynamically as a KLD via
|
|
|
|
.Xr kldload 8 .
|
|
|
|
In the former case, include
|
|
|
|
.Bd -literal -offset 4n -compact
|
|
|
|
|
|
|
|
options NETGRAPH
|
|
|
|
|
|
|
|
.Ed
|
|
|
|
in your kernel configuration file. You may also include selected
|
|
|
|
node types in the kernel compilation, for example:
|
|
|
|
.Bd -literal -offset 4n -compact
|
|
|
|
|
|
|
|
options NETGRAPH
|
|
|
|
options NETGRAPH_SOCKET
|
|
|
|
options NETGRAPH_ECHO
|
|
|
|
|
|
|
|
.Ed
|
|
|
|
.Pp
|
|
|
|
Once the
|
|
|
|
.Nm
|
|
|
|
subsystem is loaded, individual node types may be loaded at any time
|
|
|
|
as KLD modules via
|
|
|
|
.Xr kldload 8 .
|
|
|
|
Moreover,
|
|
|
|
.Nm
|
|
|
|
knows how to automatically do this; when a request to create a new
|
|
|
|
node of unknown type
|
|
|
|
.Em type
|
|
|
|
is made,
|
|
|
|
.Nm
|
|
|
|
will attempt to load the KLD module
|
|
|
|
.Dv ng_type.ko .
|
|
|
|
.Pp
|
|
|
|
Types can also be installed at boot time, as certain device drivers
|
|
|
|
may want to export each instance of the device as a netgraph node.
|
|
|
|
.Pp
|
|
|
|
In general, new types can be installed at any time from within the
|
|
|
|
kernel by calling
|
|
|
|
.Dv ng_newtype() ,
|
|
|
|
supplying a pointer to the type's
|
|
|
|
.Dv struct ng_type
|
|
|
|
structure.
|
|
|
|
.Pp
|
|
|
|
The
|
|
|
|
.Dv "NETGRAPH_INIT()"
|
|
|
|
macro automates this process by using a linker set.
|
|
|
|
.Sh EXISTING NODE TYPES
|
|
|
|
Several node types currently exist. Each is fully documented
|
|
|
|
in its own man page:
|
|
|
|
.Bl -tag -width xxx
|
|
|
|
.It SOCKET
|
|
|
|
The socket type implements two new sockets in the new protocol domain
|
|
|
|
.Dv PF_NETGRAPH .
|
|
|
|
The new sockets protocols are
|
|
|
|
.Dv NG_DATA
|
|
|
|
and
|
|
|
|
.Dv NG_CONTROL ,
|
|
|
|
both of type
|
|
|
|
.Dv SOCK_DGRAM .
|
|
|
|
Typically one of each is associated with a socket node.
|
|
|
|
When both sockets have closed, the node will shut down. The
|
|
|
|
.Dv NG_DATA
|
|
|
|
socket is used for sending and receiving data, while the
|
|
|
|
.Dv NG_CONTROL
|
|
|
|
socket is used for sending and receiving control messages.
|
|
|
|
Data and control messages are passed using the
|
|
|
|
.Xr sendto 2
|
|
|
|
and
|
|
|
|
.Xr recvfrom 2
|
|
|
|
calls, using a
|
|
|
|
.Dv struct sockaddr_ng
|
|
|
|
socket address.
|
|
|
|
.Pp
|
|
|
|
.It HOLE
|
|
|
|
Responds only to generic messages and is a ``black hole'' for data,
|
|
|
|
Useful for testing. Always accepts new hooks.
|
|
|
|
.Pp
|
|
|
|
.It 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.
|
|
|
|
.Pp
|
|
|
|
.It TEE
|
|
|
|
This node is useful for ``snooping.'' It has 4 hooks:
|
|
|
|
.Dv left ,
|
|
|
|
.Dv right ,
|
|
|
|
.Dv left2right ,
|
|
|
|
and
|
|
|
|
.Dv right2left .
|
|
|
|
Data entering from the right is passed to the left and duplicated on
|
|
|
|
.Dv right2left,
|
|
|
|
and data entering from the left is passed to the right and
|
|
|
|
duplicated on
|
|
|
|
.Dv left2right .
|
|
|
|
Data entering from
|
|
|
|
.Dv left2right
|
|
|
|
is sent to the right and data from
|
|
|
|
.Dv right2left
|
|
|
|
to left.
|
|
|
|
.Pp
|
|
|
|
.It 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.).
|
|
|
|
.Pp
|
|
|
|
.It FRAME RELAY MUX
|
|
|
|
Encapsulates/de-encapsulates Frame Relay frames.
|
|
|
|
Has a hook for the encapsulated packets (``downstream'') and one hook
|
|
|
|
for each DLCI.
|
|
|
|
.Pp
|
|
|
|
.It FRAME RELAY LMI
|
|
|
|
Automatically handles frame relay
|
|
|
|
``LMI'' (link management interface) operations and packets.
|
1999-10-30 20:30:19 +00:00
|
|
|
Automatically probes and detects which of several LMI standards
|
1999-10-21 09:06:11 +00:00
|
|
|
is in use at the exchange.
|
|
|
|
.Pp
|
|
|
|
.It TTY
|
|
|
|
This node is also a line discipline. It simply converts between mbuf
|
|
|
|
frames and sequential serial data, allowing a tty to appear as a netgraph
|
|
|
|
node. It has a programmable ``hotkey'' character.
|
|
|
|
.Pp
|
|
|
|
.It 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.
|
|
|
|
.Pp
|
|
|
|
.It 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
|
|
|
|
.Xr ifconfig 8 .
|
|
|
|
The interfaces are named
|
|
|
|
.Em ng0 ,
|
|
|
|
.Em ng1 ,
|
|
|
|
etc.
|
|
|
|
.El
|
|
|
|
.Sh NOTES
|
1999-10-30 20:30:19 +00:00
|
|
|
Whether a named node exists can be checked by trying to send a control message
|
1999-10-21 09:06:11 +00:00
|
|
|
to it (e.g.,
|
|
|
|
.Dv NGM_NODEINFO
|
|
|
|
).
|
|
|
|
If it does not exist,
|
|
|
|
.Er ENOENT
|
|
|
|
will be returned.
|
|
|
|
.Pp
|
|
|
|
All data messages are mbuf chains with the M_PKTHDR flag set.
|
|
|
|
.Pp
|
|
|
|
Nodes are responsible for freeing what they allocate.
|
|
|
|
There are three exceptions:
|
|
|
|
.Bl -tag -width xxxx
|
|
|
|
.It 1
|
|
|
|
Mbufs sent across a data link are never to be freed by the sender.
|
|
|
|
.It 2
|
1999-10-30 20:30:19 +00:00
|
|
|
Any meta-data information traveling with the data has the same restriction.
|
1999-10-21 09:06:11 +00:00
|
|
|
It might be freed by any node the data passes through, and a
|
|
|
|
.Dv NULL
|
|
|
|
passed onwards, but the caller will never free it.
|
|
|
|
Two macros
|
|
|
|
.Dv "NG_FREE_META(meta)"
|
|
|
|
and
|
|
|
|
.Dv "NG_FREE_DATA(m, meta)"
|
|
|
|
should be used if possible to free data and meta data (see
|
|
|
|
.Dv netgraph.h ")."
|
|
|
|
.It 3
|
|
|
|
Messages sent using
|
|
|
|
.Dv ng_send_message()
|
|
|
|
are freed by the callee. As in the case above, the addresses
|
|
|
|
associated with the message are freed by whatever allocated them so the
|
|
|
|
recipient should copy them if it wants to keep that information.
|
|
|
|
.El
|
|
|
|
.Sh FILES
|
|
|
|
.Bl -tag -width xxxxx -compact
|
|
|
|
.It Pa /sys/netgraph/netgraph.h
|
1999-10-30 20:30:19 +00:00
|
|
|
Definitions for use solely within the kernel by
|
1999-10-21 09:06:11 +00:00
|
|
|
.Nm
|
|
|
|
nodes.
|
|
|
|
.It Pa /sys/netgraph/ng_message.h
|
|
|
|
Definitions needed by any file that needs to deal with
|
|
|
|
.Nm
|
|
|
|
messages.
|
|
|
|
.It Pa /sys/netgraph/ng_socket.h
|
|
|
|
Definitions needed to use
|
|
|
|
.Nm
|
|
|
|
socket type nodes.
|
|
|
|
.It Pa /sys/netgraph/ng_{type}.h
|
|
|
|
Definitions needed to use
|
|
|
|
.Nm
|
|
|
|
{type}
|
|
|
|
nodes, including the type cookie definition.
|
|
|
|
.It Pa /modules/netgraph.ko
|
|
|
|
Netgraph subsystem loadable KLD module.
|
|
|
|
.It Pa /modules/ng_{type}.ko
|
|
|
|
Loadable KLD module for node type {type}.
|
|
|
|
.El
|
|
|
|
.Sh USER MODE SUPPORT
|
|
|
|
There is a library for supporting user-mode programs that wish
|
|
|
|
to interact with the netgraph system. See
|
|
|
|
.Xr netgraph 3
|
|
|
|
for details.
|
|
|
|
.Pp
|
|
|
|
Two user-mode support programs,
|
|
|
|
.Xr ngctl 8
|
|
|
|
and
|
|
|
|
.Xr nghook 8 ,
|
|
|
|
are available to assist manual configuration and debugging.
|
|
|
|
.Pp
|
|
|
|
There are a few useful techniques for debugging new node types.
|
|
|
|
First, implementing new node types in user-mode first
|
|
|
|
makes debugging easier.
|
|
|
|
The
|
|
|
|
.Em tee
|
|
|
|
node type is also useful for debugging, especially in conjunction with
|
|
|
|
.Xr ngctl 8
|
|
|
|
and
|
|
|
|
.Xr nghook 8 .
|
|
|
|
.Sh SEE ALSO
|
|
|
|
.Xr socket 2 ,
|
|
|
|
.Xr netgraph 3 ,
|
|
|
|
.Xr ngctl 8 ,
|
|
|
|
.Xr nghook 8 ,
|
1999-11-19 04:41:09 +00:00
|
|
|
.Xr ng_async 8 ,
|
|
|
|
.Xr ng_cisco 8 ,
|
|
|
|
.Xr ng_echo 8 ,
|
|
|
|
.Xr ng_frame_relay 8 ,
|
|
|
|
.Xr ng_hole 8 ,
|
|
|
|
.Xr ng_iface 8 ,
|
|
|
|
.Xr ng_ksocket 8 ,
|
|
|
|
.Xr ng_lmi 8 ,
|
|
|
|
.Xr ng_ppp 8 ,
|
|
|
|
.Xr ng_pppoe 8 ,
|
|
|
|
.Xr ng_rfc1490 8 ,
|
|
|
|
.Xr ng_socket 8 ,
|
|
|
|
.Xr ng_tee 8 ,
|
|
|
|
.Xr ng_tty 8 ,
|
|
|
|
.Xr ng_UI 8 ,
|
|
|
|
.Xr ng_vjc 8 ,
|
1999-10-21 09:06:11 +00:00
|
|
|
.Xr ng_{type} 8 .
|
|
|
|
.Sh HISTORY
|
|
|
|
The
|
|
|
|
.Nm
|
|
|
|
system was designed and first implemented at Whistle Communications, Inc.
|
|
|
|
in a version FreeBSD 2.2 customized for the Whistle InterJet.
|
|
|
|
.Sh AUTHORS
|
|
|
|
Julian Elischer <julian@whistle.com>, with contributions by
|
|
|
|
Archie Cobbs <archie@whistle.com>.
|