<?xml version='1.0'?> <!-- -*- docbook -*- -->
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">

<article>
  <articleinfo>
    <title>mast</title>

    <author>
      <firstname>Michael</firstname>
      <surname>Richardson</surname>
      <affiliation>
         <address><email>mcr@sandelman.ottawa.on.ca</email></address>
      </affiliation>
    </author>

    <copyright>
      <year>2003</year>
      <holder>Michael Richardson</holder>
    </copyright>
  </articleinfo>

  <section>
    <title>Reference</title>

<refentry id="mast">

<refmeta>
<refentrytitle>mast</refentrytitle>
<manvolnum>4</manvolnum>
</refmeta>

<refnamediv>
<refname>mast</refname>
<refpurpose>pseudo-driver for attaching tunnelling protocols</refpurpose>
</refnamediv>

<refsynopsisdiv>

<funcsynopsis>
<funcsynopsisinfo>
#include &lt;net/mast.h&gt;
</funcsynopsisinfo>
<funcprototype>
  <funcdef>struct device *<function>mast_init</function></funcdef>
  <paramdef>int <parameter>family</parameter></paramdef>
  <paramdef>struct mast_callbacks *<parameter>callbacks</parameter></paramdef>
  <paramdef>unsigned int <parameter>flags</parameter></paramdef>
  <paramdef>char *<parameter>unit</parameter></paramdef>
  <paramdef>unsigned int <parameter>max_flowref</parameter></paramdef>
  <paramdef>void *<parameter>context</parameter></paramdef>
</funcprototype>

<funcprototype>
  <funcdef>int <function>packet_encap</function></funcdef>
  <paramdef>struct device *<parameter>mast</parameter></paramdef>
  <paramdef>void *<parameter>context</parameter></paramdef>
  <paramdef>struct skb *<parameter>skb</parameter></paramdef>
  <paramdef>int <parameter>flowref</parameter></paramdef>
</funcprototype>

<funcprototype>
  <funcdef>int <function>link_inquire</function></funcdef>
  <paramdef>struct device *<parameter>mast</parameter></paramdef>
  <paramdef>void *<parameter>context</parameter></paramdef>
</funcprototype>

<funcprototype>
  <funcdef>int <function>mast_linkstat</function></funcdef>
  <paramdef>struct device *<parameter>mast</parameter></paramdef>
  <paramdef>int <parameter>flowref</parameter></paramdef>
  <paramdef>int <parameter>status</parameter></paramdef>
</funcprototype>

<funcprototype>
  <funcdef>int <function>mast_setreference</function></funcdef>
  <paramdef>struct device *<parameter>mast</parameter></paramdef>
  <paramdef>int <parameter>default_flowref</parameter></paramdef>
</funcprototype>

<funcprototype>
  <funcdef>int <function>mast_setneighbour</function></funcdef>
  <paramdef>struct device *<parameter>mast</parameter></paramdef>
  <paramdef>struct sockaddr *<parameter>source</parameter></paramdef>
  <paramdef>struct sockaddr *<parameter>destination</parameter></paramdef>
  <paramdef>int <parameter>flowref</parameter></paramdef>
</funcprototype>

</funcsynopsis>

</refsynopsisdiv>

<refsect1><title>Description</title>
<para>
The
<application>mast</application>
network interface is a pseudo device that allows tunnelling protocols to
be attached to the base of the device, and routing protocols and daemons to
the top. The metaphor is that of a blimp attached to a mooring post or mast.
</para>

<para>
<application>mast</application> stands for Mooring And Status Tunnel.
</para>

<para>
The network interfaces are named anything that can fit in 16 printable characters.  We suggest
<function>mast0</function>, <function>mast1</function>
and so on, as many as desired, but they could also be named
<function>mast-rome</function> or even <function>vpn-rome</function>
or other more descriptive names.  The names should be unique in the namespace
of the network devices.
</para>

<para>
They are created with the "ip tunnel" command. (XXX? are they. Maybe, maybe not.)
</para>

<para>
The <application>mast</application> device provides a way to anchor routing daemon to virtual
topologies. It provides a consistent abstraction to various kinds of tunnelling
technology: IP-encap (protocol 4), IPv6 (protocol 41), GRE (protocol 47),
ESP (protocol 50), AH (protocol 51), IPIP (protocol 94) and ENCAP (protocol 98).
</para>

<para>
There are three ways that a <application>mast</application> can be used. They
correspond to how additional
information (i.e. policy) is attached to the packets that are directed toward
the device. <application>mast</application> devices are bi-directional
devices, but the flow of the packets that emerge do so in a uniform manner.
</para>

<para>
The first way is called the PPP method.
A <application>mast</application> is considered to
be portal to which
packets that need a predefined kind of encapsulation may be sent.
The <application>mast</application>
acts as a point to point device - a virtual leased line - sending all packets
into the an underlying tunnel mechanism, having attached a default security
policy to each packet. (As is described under "SECURITY POLICY", the
nfmark is used).
A <application>mast</application> device used in this way should be
indistinguishable from a SLIP
interface - it has no layer two protocol. The layer two link status of
the <application>mast</application>
device may reflect the state of the dead peer detection status for the remote
end point, if this feature has been enabled.
</para>

<para>
The second way that a <application>mast</application> device may be used is
as an entry into a
non-broadcast, multiple access encapsulation media. The is the NFMARK
method. The choice of a
particular tunnel is indicated by setting bits in the control structure (the
skb). This is described under "SECURITY POLICY".
</para>

<para>
The third way that a <application>mast</application> device may be used is
with a virtual link
layer. This is the NMBA method.
This is the This is a variation of the previous method - the device is still a
non-broadcast, multiple access device, except that the <application>mast</application> device
supports a layer two similar to ARP. The layer two information that the network
stack attaches to each packet will be used to determine which tunnel will be
used. The <application>mast</application> device will keep the neighbour cache updated with liveness
info. If the tunnel to a given neighbour is known to be down (such as,
because of a lack of a key, or expiration of such), then the neighbour cache
entry will be removed.
</para>

<para>
Packets that are sent upwards (in the direction of decapsulation) from
the <application>mast</application> device will be marked by the tunnel on
which the packet was received.
The choice of which <application>mast</application> device to emerge from
is also defined by the tunnel decapsulation mechanism. Typically, a unique
device will be created per major policy category. This is done to simplify the
firewall rules.
</para>

<para>
The PPP method is most appropriate for use on the client side of a road
warrior configuration, or when there is a sufficiently small number of VPN tunnels
that it is practical (or desirable) for each tunnel to have its own device
associated with it. The simplification of firewall rules for output is the
primary benefit of this mode.
</para>

<para>
The NFMARK mechanism is used by more traditional VPN topologies, and by
Opportunistic Encryption. These two categories of use mandate a different
output device per major policy. Both would use specific setting of policy
bits (skb->nfmark) for selection of outgoing policy.
</para>

<para>
The NMBA mechanism, where an ARP-like layer two is maintained, is most
appropriate for layered systems like the xbone, where there may be too many
tunnels for it to be practical to create a device per tunnel. At the same
time, the reachability information that the layer-two tables provide can be
used by routing systems to determine the optimal path.
</para>

<para>
The <application>mast</application> device permits kernel code
to create them with:
<programlisting>
	struct device *mast;

	mast = mast_init(family, callbacks, flags,
	                 unit, max_flowref, context)
</programlisting>
</para>

<para>
A new <application>mast</application> device is create per address family.
This is not strictly necessary, but may simplify policy checks as well.
</para>

<variablelist>
<varlistentry><term><parameter>family</parameter></term>
<listitem>
<para>
is AF_INET or AF_INET6.
</para>
</listitem>
</varlistentry>

<varlistentry><term><parameter>flags</parameter></term>
<listitem>
<para>
is one of
</para>

<para>
MAST_PPP:the device will operate only as a point to point device
            ignoring any bits set in the
            <structname>nfmark</structname> field.
</para>

<para>MAST_NFMARK:
      the device will examine the <structname>nfmark</structname> field,
            extracting bits from this field to form an SArefence,
            which is passed to the encapsulation routine.
      </para>

<para>
MAST_NBMA:
the device will examine virtual layer two information
            pointed to by the <structname>skb->mac.raw</structname> field.
      </para>

</listitem>
</varlistentry>

<varlistentry><term><parameter>unit</parameter></term>
<listitem>
      <para>is an integer X, the unit number, and results in the creation
		of the appropriate mastX device. If this unit number is
		in use, then an error will result, and NULL will be returned.
      </para>
</listitem>
</varlistentry>

<varlistentry><term><parameter>max_flowref</parameter></term>
<listitem>
      <para>is the theoretical highest flowref that can be assigned. It
            is recorded for sanity checking. It may also be used for scaling
            of virtual layer-2 structures.
      </para>
</listitem>
</varlistentry>

<varlistentry><term><parameter>callbacks</parameter></term>
<listitem>
      <para>
        The callback is a structure containing function pointers for
        <function>packet_encap</function> and <function>link_inquire</function>.

      </para>
</listitem>
</varlistentry>

<varlistentry><term><parameter>context</parameter></term>
<listitem>
      <para>
        The context contains mast sub-type-specific information.

      </para>
</listitem>
</varlistentry>

<programlisting>
      int packet_encap (struct device *mast, void *context,
                         struct skb *skb, int flowref);
</programlisting>

<varlistentry><term><parameter>mast</parameter></term>
<listitem>
      <para>
        The mast is a struct device * previously
	created by <function>mast_init</function>.

      </para>
</listitem>
</varlistentry>

<varlistentry><term><parameter>skb</parameter></term>
<listitem>
      <para>
	The skb is a struct sk_buff * passed down for processing.
      </para>
</listitem>
</varlistentry>

<varlistentry><term><parameter>flowref</parameter></term>
<listitem>
      <para>
	The flowref is a reference to a policy to be used for packet
	processing.
      </para>
</listitem>
</varlistentry>

<programlisting>
       int mast_linkstat (struct device *mast, int flowref,
                          int status);
</programlisting>

<varlistentry><term><parameter>status</parameter></term>
<listitem>
      <para>
	The status is a flag indicating the link state.

      </para>
</listitem>
</varlistentry>

<varlistentry><term><parameter>default_flowref</parameter></term>
<listitem>
      <para>
	The default_flowref is a reference to a default policy to be used for packet processing.

      </para>
</listitem>
</varlistentry>

<programlisting>
       int mast_setneighbour (struct device *mast,
                              struct sockaddr *source,
                              struct sockaddr *destination,
                              int flowref);
</programlisting>

<varlistentry><term><parameter>source</parameter> and <parameter>destination</parameter></term>
<listitem>
      <para>
	The source and destination are IPv4 or IPv6 addresses.
      </para>
</listitem>
</varlistentry>

</variablelist>

<para>
The <function>packet_encap</function> callback is called by the mast
device when a packet has been forwarded into the <application>mast</application> device in some
fashion. The function will be called with the
<parameter>context</parameter> that was provided in the
<function>mast_init</function> call.
</para>

<para>
The packet to be processed will be passed in the
<parameter>skb</parameter> parameter. The flow reference
will have been extracted and passed in the
<parameter>flowref</parameter> parameter.
</para>

<para>
The link_inquire() function is a request from
the <application>mast</application> device to have its
link status updated by the tunnel apparatus. Link status can be
updated with the <function>mast_linkstat</function> function.
</para>

<para>
In the link_inquire call(), status is up==1/down==0.
Some <application>mast</application> devices may maintain per-flowref link
status (in the pseudo-ARP case), in which case the flowref should be
provided. A flowref of -1 updates the global link status.
</para>

<para>
A <application>mast</application> device may have its default
flow reference set via the
<function>mast_setflowref</function> function.
</para>

<para>
A <application>mast</application> device examines packets that
it receives, looks at the appropriate
parts of the nfmark and turns that into the reference #. If these bits are
zero, then the default flow reference is used. If the default
flow reference is not
set, then the packet is dropped as a transmit error.
</para>

<para>
The <function>mast_setneighbour</function> function will be filled out at a later time.
</para>

</refsect1>

<refsect1><title>SECURITY POLICY</title>
<para>
When the <application>mast</application> device is configured to be
in <constant>MAST_NFMARK</constant> mode, it will examine the
<structname>skb->nfmark</structname> field of each incoming
packet. The upper 24 bits of the <structname>nfmark</structname> will
be extracted. If bit 31 is set, then the
<structname>nfmark</structname> will be considered to be have been
initialized. Bits 8 through 30 are then shifted to the right, resulting
in a 23 bit number. This is considered the flowref.
</para>

<para>If the bit is not set, then the packet will have the default flow reference
applied to it.
</para>

</refsect1>
</refentry>
</section>
</article>






