ng_daphne is a netgraph kernel module for FreeBSD that allows the easy
creation of multihop ad hoc networks. It employs the GSR (Global State
Routing) algorithm and encapsulates all data packets in order to give
the impression to upper layers that all network nodes are within one hop
from each other. The ng_daphne node transparently routes data packets
according to their hardware address.

The ng_daphne module has 4 hooks: upstream, downstream, pass, info.

Downstream can be connected only to the 'lower' hook of a node of type 'ether'.
This node should correspond to the wireless interface that will be used
for the ad hoc network creation (e.g. wi0). As soon as the downstream hook
gets connected, ng_daphne gets the hardware address node of the interface
and starts transmitting and listening to routing updates in order to get
acquainted to the network topology.

Upstream can be connected only to another netgraph node of type 'eiface'.
This means that a virtual interface of type "ether" should be created and
get linked to the netgraph node. If the ng_daphne already knows the hardware
address of the wireless interface, it automatically configures the virtual
interface (e.g. nge0) to use it too.

Pass is used for non-encapsulated traffic that is received via the downstream
hook and should be connected to the 'upper' hook of the 'ether' node that
was used for the downstream hook. Also, if data is received on this hook, it
will be transmitted as is to the downlink hook.

Info is used for debugging purposes. If it is connected to another node,
ng_daphne periodically sents the routing table via this hook. This is used
primarily for debugging purposes, but also for making topology information
accessible from user-land programs.

Besides the 'info' hook, all three other hooks should be connected as outlined
above. When these three hooks are connected, ng_daphne operation is as follows.
For example, the 'pass' and 'downstream' hooks are connected to the 'upper' and
'lowe' hooks of the wi0 interface. Furthermore, the ng_daphne 'upstream' hook
is connected to the 'ether' hook of the nge0 interface. Consequently, the logical
interfaces wi0 and nge0 correspond to the same physical interface, the one that
originally was solely used for wi0. The logical wi0 interface is used for traffic
that is not encapsulated according to ng_daphne. On the other hand, nge0
en- and de-capsulates data packets, in order to route them via relaying network
nodes.

When encapsulating data packets, a header is added to the packet that was received
from the 'upstream' hook. This header is 22 bytes long and contains information such
as type of contents, end-to-end sender, end-to-end destination etc. Because the
network stack of FreeBSD is not aware of this increase in packet length, the MTU of
the virtual interface should be at least 22 bytes less than the MTU of the physical
interface, in order to avoid frames getting discarded because they were found to be
oversized. Packets that were encapsulated according to the ng_daphne rules can be
told apart from non-encapsulated ones, since all encapsulated frames use (arbitrarily)
the ethertype 0x4444. Since, what ng_daphne does is the equivalent of a bridge, it does
not matter what kind of protocol (e.g. IPv4, IPv6) is used by the upper layers.

Please note that this is the first version of ng_daphne and most probably there are
many bugs in it, eventhough (hopefully) kernel panics should not occur. Also, this
implementation of GSR does not conform to any standards or guidelines used by IETF
and most specifically the MANET group on multihop ad hoc networks.

In order to enable the multihop ad hoc routing capabilities of ng_daphne, first
load the ng_ether, ng_eiface and ng_daphne modules with kldload. Then, you should
connect the hooks using ngctl:

# Create a ng_daphne node and connect its downstream hook to the lower hook of a
# wireless interface, e.g. wi0
mkpeer wi0: daphne lower downstream

# Give a name to the newly created node, for example 'dp'
name wi0:lower dp

# Create a virtual interface of type 'eiface' and connect its 'ether' hook to
# upstream
mkpeer dp: eiface upstream ether

# Connect the 'pass' hook of ng_daphne to the 'upper' hook of the physical
# interface
connect wi0: dp: upper pass

Now, you should alter the MTU of the virtual interface. Most probably the MTU of
the physical interface is 1500, consequently the MTU of the virtual interface
should be set to 1478. Alter this value with ifconfig.

ifconfig nge0 mtu 1478

Now, you can use the virtual interface to reach destinations that are not within
one hop distance.

- Gerasimos Dimitriadis
gedimitr@auth.gr