convert manual.html to docbook
authorBrendan O'Dea <bod@optus.net>
Tue, 23 May 2006 14:28:25 +0000 (14:28 +0000)
committerBrendan O'Dea <bod@optus.net>
Tue, 23 May 2006 14:28:25 +0000 (14:28 +0000)
Changes
Docs/common/config.xml [new file with mode: 0644]
Docs/common/docbook.css [new file with mode: 0644]
Docs/manual.html [deleted file]
Docs/manual/manual.xml [new file with mode: 0644]
l2tpns.spec

diff --git a/Changes b/Changes
index c920f8c..0029cfd 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,8 +1,9 @@
-* Fri Apr 28 2006 Brendan O'Dea <bod@optus.net> 2.2.0
+* Wed May 24 2006 Brendan O'Dea <bod@optus.net> 2.2.0
 - Only poll clifd if successfully bound.
 - Add "Practical VPNs" document from Liran Tal as Docs/vpn .
 - Add Multilink support from Khaled Al Hamwi.
 - Remove non-working setuid option.
+- Convert manual.html to Docbook.
 
 * Tue Apr 18 2006 Brendan O'Dea <bod@optus.net> 2.1.18
 - Don't shutdown on TerminateReq, wait for CDN.
diff --git a/Docs/common/config.xml b/Docs/common/config.xml
new file mode 100644 (file)
index 0000000..6207ae3
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+  <xsl:param name="html.stylesheet" select="'../common/docbook.css'"/>
+</xsl:stylesheet>
diff --git a/Docs/common/docbook.css b/Docs/common/docbook.css
new file mode 100644 (file)
index 0000000..00e3974
--- /dev/null
@@ -0,0 +1,69 @@
+div.article > div.titlepage {
+    text-align: center;
+}
+
+.abstract {
+    text-align: justify;
+}
+
+.title {
+    font-family: sans-serif;
+    font-weight: bolder;
+    margin-bottom: 0.5em;
+}
+
+.sect2, .sect2, .sect3, .sect4 {
+    margin-left: 2%;
+    margin-right: 2%;
+}
+
+.sect2 .title, .sect2 .title, .sect3 .title, .sect4 .title {
+    margin-left: 0;
+    margin-right: 0;
+}
+
+.synopsis, .screen, .programlisting {
+    font-family: monospace;
+    font-size: 1em;
+    display: block;
+    padding: 10px;
+    border: 1px solid #bbb;
+    background-color: #eee;
+    color: #000;   
+    overflow: auto;
+    border-radius: 2.5px;
+    -moz-border-radius: 2.5px;
+    margin: 0.5em 2em;
+}
+
+.programlisting em {
+    color: red;
+}
+
+.hanging-indent {
+    margin-left: 4em;
+    text-indent: -2em;
+}
+
+table {
+    margin: 0.5em 2em;
+    border: 1px solid #bbb;
+    border-collapse: collapse;
+}
+
+td {
+    vertical-align: baseline;
+}
+
+thead {
+    background-color: #eee;
+}
+
+td table {
+    margin: 0;
+    border: 0;
+}
+
+td {
+    border: 1px solid #bbb;
+}
\ No newline at end of file
diff --git a/Docs/manual.html b/Docs/manual.html
deleted file mode 100644 (file)
index 5c830f2..0000000
+++ /dev/null
@@ -1,1074 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-    "http://www.w3.org/TR/html4/loose.dtd">
-
-<HTML>
-<HEAD>
-<TITLE>L2TPNS Manual</TITLE>
-<STYLE TYPE="text/css">
-H1 {
-       text-align: center;
-}
-
-H2 {
-       border-top: 1px solid black;
-       border-bottom: 1px solid black;
-       background-color: lightblue;
-       padding-left: 10px;
-}
-
-H3 {
-       text-decoration: underline;
-}
-</STYLE>
-</HEAD>
-<BODY>
-<H1>L2TPNS Manual</H1>
-<OL>
-    <LI><A HREF="#Overview">Overview</A></LI>
-    <LI><A HREF="#Installation">Installation</A>
-       <OL>
-           <LI><A HREF="#Requirements">Requirements</A></LI>
-           <LI><A HREF="#Compile">Compile</A></LI>
-           <LI><A HREF="#Install">Install</A></LI>
-           <LI><A HREF="#Running">Running</A></LI>
-       </OL>
-    </LI>
-    <LI><A HREF="#Configuration">Configuration</A>
-       <OL>
-           <LI><A HREF="#startup-config">startup-config</A></LI>
-           <LI><A HREF="#users">users</A></LI>
-           <LI><A HREF="#ip-pool">ip_pool</A></LI>
-           <LI><A HREF="#build-garden">build-garden</A></LI>
-       </OL>
-    </LI>
-    <LI><A HREF="#ControllingtheProcess">Controlling the Process</A>
-       <OL>
-           <LI><A HREF="#Command-LineInterface">Command-Line Interface</A></LI>
-           <LI><A HREF="#nsctl">nsctl</A></LI>
-           <LI><A HREF="#Signals">Signals</A></LI>
-       </OL>
-    </LI>
-    <LI><A HREF="#Throttling">Throttling</A></LI>
-    <LI><A HREF="#Interception">Interception</A></LI>
-    <LI><A HREF="#Authentication">Authentication</A></LI>
-    <LI><A HREF="#Plugins">Plugins</A></LI>
-    <LI><A HREF="#WalledGarden">Walled Garden</A></LI>
-    <LI><A HREF="#Filtering">Filtering</A></LI>
-    <LI><A HREF="#Clustering">Clustering</A></LI>
-    <LI><A HREF="#Routing">Routing</A></LI>
-    <LI><A HREF="#Performance">Performance</A></LI>
-</OL>
-
-<H2 ID="Overview">Overview</H2>
-l2tpns is half of a complete L2TP implementation.  It supports only the
-LNS side of the connection.<P>
-
-L2TP (Layer 2 Tunneling Protocol) is designed to allow any layer 2
-protocol (e.g. Ethernet, PPP) to be tunneled over an IP connection.  l2tpns
-implements PPP over L2TP only.<P>
-
-There are a couple of other L2TP implementations, of which <A
-HREF="http://sourceforge.net/projects/l2tpd">l2tpd</A> is probably the
-most popular.  l2tpd also will handle being either end of a tunnel, and
-is a lot more configurable than l2tpns.  However, due to the way it works,
-it is nowhere near as scalable.<P>
-
-l2tpns uses the TUN/TAP interface provided by the Linux kernel to receive
-and send packets.  Using some packet manipulation it doesn't require a
-single interface per connection, as l2tpd does.<P>
-
-This allows it to scale extremely well to very high loads and very high
-numbers of connections.<P>
-
-It also has a plugin architecture which allows custom code to be run
-during processing.  An example of this is in the walled garden module
-included.<P>
-
-<BR>
-<EM>Documentation is not my best skill.  If you find any problems
-with this document, or if you wish to contribute, please email <A
-HREF="mailto:l2tpns-users@lists.sourceforge.net?subject=L2TPNS+Documentation">the mailing list</A>.</EM><P>
-
-<H2 ID="Installation">Installation</H2>
-<H3 ID="Requirements">Requirements</H3>
-
-<OL>
-<LI>Linux kernel version 2.4 or above, with the Tun/Tap interface either
-compiled in, or as a module.</LI>
-
-<LI>libcli 1.8.0 or greater.<BR>You can get this from <A
-HREF="http://sourceforge.net/projects/libcli">http://sourceforge.net/projects/libcli</A></LI>
-</OL>
-
-<H3 ID="Compile">Compile</H3>
-
-You can generally get away with just running <B>make</B> from the source
-directory.  This will compile the daemon, associated tools and any modules
-shipped with the distribution.<P>
-
-<H3 ID="Install">Install</H3>
-
-After you have successfully compiled everything, run <B>make
-install</B> to install it.  By default, the binaries are installed into
-<EM>/usr/sbin</EM>, the configuration into <EM>/etc/l2tpns</EM>, and the
-modules into <EM>/usr/lib/l2tpns</EM>.<P>
-
-You will definately need to edit the configuration files before you
-start.  See the <A HREF="#Configuration">Configuration</A> section for
-more information.<P>
-
-<H3 ID="Running">Running</H3>
-
-You only need to run <B>/usr/sbin/l2tpns</B> as root to start it.  It does
-not detach to a daemon process, so you should perhaps run it from init.<P>
-
-By default there is no log destination set, so all log messages will go to
-stdout.<P>
-
-<H2 ID="Configuration">Configuration</H2>
-
-All configuration of the software is done from the files installed into
-/etc/l2tpns.
-
-<H3 ID="startup-config">startup-config</H3>
-
-This is the main configuration file for l2tpns.  The format of the file is a
-list of commands that can be run through the command-line interface.  This
-file can also be written directly by the l2tpns process if a user runs the
-<EM>write memory</EM> command, so any comments will be lost.  However if your
-policy is not to write the config by the program, then feel free to comment
-the file with a # or ! at the beginning of the line.<P>
-
-A list of the possible configuration directives follows.  Each of these
-should be set by a line like:<P>
-<PRE>
-set configstring "value"
-set ipaddress 192.168.1.1
-set boolean true
-</PRE>
-
-<P>
-<UL>
-<LI><B>debug</B> (int)<BR>
-Sets the level of messages that will be written to the log file.  The value
-should be between 0 and 5, with 0 being no debugging, and 5 being the
-highest.  A rough description of the levels is:
-       <OL>
-       <LI VALUE=0>Critical Errors - Things are probably broken</LI>
-       <LI>Errors - Things might have gone wrong, but probably will recover</LI>
-       <LI>Warnings - Just in case you care what is not quite perfect</LI>
-       <LI>Information - Parameters of control packets</LI>
-       <LI>Calls - For tracing the execution of the code</LI>
-       <LI>Packets - Everything, including a hex dump of all packets processed...  probably twice</LI>
-       </OL><P>
-Note that the higher you set the debugging level, the slower the program
-will run.  Also, at level 5 a LOT of information will be logged.  This should
-only ever be used for working out why it doesn't work at all.
-</LI>
-
-<LI><B>log_file</B> (string)<BR>
-This will be where all logging and debugging information is written
-to.  This may be either a filename, such as <EM>/var/log/l2tpns</EM>, or
-the special magic string <EM>syslog:facility</EM>, where <EM>facility</EM>
-is any one of the syslog logging facilities, such as local5.
-</LI>
-
-<LI><B>pid_file</B> (string)<BR>
-If set, the process id will be written to the specified file.  The
-value must be an absolute path.
-</LI>
-
-<LI><B>l2tp_secret</B> (string)<BR>
-The secret used by l2tpns for authenticating tunnel request.  Must be
-the same as the LAC, or authentication will fail.  Only actually be
-used if the LAC requests authentication.
-</LI>
-
-<LI><B>l2tp_mtu</B> (int)<BR>
-MTU of interface for L2TP traffic (default: 1500).  Used to set link
-MRU and adjust TCP MSS.
-</LI>
-
-<LI><B>ppp_restart_time</B> (int)<BR>
-<B>ppp_max_configure</B> (int)<BR>
-<B>ppp_max_failure</B> (int)<BR>
-PPP counter and timer values, as described in &sect;4.1 of
-<a href="ftp://ftp.rfc-editor.org/in-notes/rfc1661.txt">RFC1661</a>.
-</LI>
-
-<LI><B>primary_dns</B> (ip address)
-<LI><B>secondary_dns</B> (ip address)<BR>
-Whenever a PPP connection is established, DNS servers will be sent to the
-user, both a primary and a secondary.  If either is set to 0.0.0.0, then that
-one will not be sent.
-</LI>
-
-<LI><B>primary_radius</B> (ip address)
-<LI><B>secondary_radius</B> (ip address)<BR>
-Sets the RADIUS servers used for both authentication and accounting. 
-If the primary server does not respond, then the secondary RADIUS
-server will be tried.<br>
-<strong>Note:</strong> in addition to the source IP address and
-identifier, the RADIUS server <strong>must</strong> include the source
-port when detecting duplicates to supress (in order to cope with a
-large number of sessions comming on-line simultaneously l2tpns uses a
-set of udp sockets, each with a seperate identifier).
-</LI>
-
-<LI><B>primary_radius_port</B> (short)
-<LI><B>secondary_radius_port</B> (short)<BR>
-Sets the authentication ports for the primary and secondary RADIUS
-servers.  The accounting port is one more than the authentication
-port.  If no RADIUS ports are given, the authentication port defaults
-to 1645, and the accounting port to 1646.
-</LI>
-
-<LI><B>radius_accounting</B> (boolean)<BR>
-If set to true, then RADIUS accounting packets will be sent.  This
-means that a Start record will be sent when the session is
-successfully authenticated, and a Stop record will be sent when the
-session is closed.
-</LI>
-
-<LI><B>radius_secret</B> (string)<BR>
-This secret will be used in all RADIUS queries.  If this is not set then
-RADIUS queries will fail.
-</LI>
-
-<LI><B>radius_authtypes</B> (string)</BR>
-A comma separated list of supported RADIUS authentication methods
-(<B>pap</B> or <B>chap</B>), in order of preference (default <B>pap</B>).
-</LI>
-
-<LI><B>radius_dae_port</B> (short)<BR>
-Port for DAE RADIUS (Packet of Death/Disconnect, Change of Authorization)
-requests (default: <B>3799</B>).
-</LI>
-
-<LI><B>allow_duplicate_users</B> (boolean)</BR>
-Allow multiple logins with the same username.  If false (the default),
-any prior session with the same username will be dropped when a new
-session is established.
-</LI>
-
-<LI><B>bind_address</B> (ip address)<BR>
-When the tun interface is created, it is assigned the address
-specified here.  If no address is given, 1.1.1.1 is used.  Packets
-containing user traffic should be routed via this address if given,
-otherwise the primary address of the machine.
-</LI>
-
-<LI><B>peer_address</B> (ip address)<BR>
-Address to send to clients as the default gateway.
-</L1>
-
-<LI><B>send_garp</B> (boolean)<BR>
-Determines whether or not to send a gratuitous ARP for the
-bind_address when the server is ready to handle traffic (default: 
-true).<BR>
-This value is ignored if BGP is configured.
-</LI>
-
-<LI><B>throttle_speed</B> (int)<BR>
-Sets the default speed (in kbits/s) which sessions will be limited to. 
-If this is set to 0, then throttling will not be used at all.  Note: 
-You can set this by the CLI, but changes will not affect currently
-connected users.
-</LI>
-
-<LI><B>throttle_buckets</B> (int)<BR>
-Number of token buckets to allocate for throttling.  Each throttled
-session requires two buckets (in and out).
-</LI>
-
-<LI><B>accounting_dir</B> (string)<BR>
-If set to a directory, then every 5 minutes the current usage for
-every connected use will be dumped to a file in this directory.  Each
-file dumped begins with a header, where each line is prefixed by #. 
-Following the header is a single line for every connected user, fields
-separated by a space.<BR> The fields are username, ip, qos,
-uptxoctets, downrxoctets.  The qos field is 1 if a standard user, and
-2 if the user is throttled.
-</LI>
-
-<LI><B>setuid</B> (int)<BR>
-After starting up and binding the interface, change UID to this.  This
-doesn't work properly.
-</LI>
-
-<LI><B>dump_speed</B> (boolean)<BR>
-If set to true, then the current bandwidth utilization will be logged every
-second.  Even if this is disabled, you can see this information by running
-the <EM>uptime</EM> command on the CLI.
-</LI>
-
-<LI><B>multi_read_count</B> (int)<BR>
-Number of packets to read off each of the UDP and TUN fds when
-returned as readable by select (default:  10).  Avoids incurring the
-unnecessary system call overhead of select on busy servers.
-</LI>
-
-<LI><B>scheduler_fifo</B> (boolean)<BR>
-Sets the scheduling policy for the l2tpns process to SCHED_FIFO.  This
-causes the kernel to immediately preempt any currently running SCHED_OTHER
-(normal) process in favour of l2tpns when it becomes runnable. 
-Ignored on uniprocessor systems.
-</LI>
-
-<LI><B>lock_pages</B> (boolean)<BR>
-Keep all pages mapped by the l2tpns process in memory.
-</LI>
-
-<LI><B>icmp_rate</B> (int)<BR>
-Maximum number of host unreachable ICMP packets to send per second.
-</LI>
-
-<LI><B>packet_limit</B> (int><BR>
-Maximum number of packets of downstream traffic to be handled each
-tenth of a second per session.  If zero, no limit is applied (default: 
-0).  Intended as a DoS prevention mechanism and not a general
-throttling control (packets are dropped, not queued).
-</LI>
-
-<LI><B>cluster_address</B> (ip address)<BR>
-Multicast cluster address (default:  239.192.13.13).  See the section
-on <A HREF="#Clustering">Clustering</A> for more information.
-</LI>
-
-<LI><B>cluster_interface</B> (string)<BR>
-Interface for cluster packets (default: eth0).
-</LI>
-
-<LI><B>cluster_mcast_ttl</B> (int)<BR>
-TTL for multicast packets (default: 1).
-</LI>
-
-<LI><B>cluster_hb_interval</B> (int)<BR>
-Interval in tenths of a second between cluster heartbeat/pings.
-</LI>
-
-<LI><B>cluster_hb_timeout</B> (int)<BR>
-Cluster heartbeat timeout in tenths of a second.  A new master will be
-elected when this interval has been passed without seeing a heartbeat
-from the master.
-</LI>
-
-<LI><B>cluster_master_min_adv</B> (int)<BR>
-Determines the minumum number of up to date slaves required before the
-master will drop routes (default: 1).
-</LI>
-</UL>
-
-<P>BGP routing configuration is entered by the command:
-The routing configuration section is entered by the command
-<DL><DD><B>router bgp</B> <I>as</I></DL>
-where <I>as</I> specifies the local AS number.
-
-<P>Subsequent lines prefixed with
-<DL><DD><B>neighbour</B> <I>peer</I></DL>
-define the attributes of BGP neighhbours.  Valid commands are:
-<DL>
-  <DD><B>neighbour</B> <I>peer</I> <B>remote-as</B> <I>as</I>
-  <DD><B>neighbout</B> <I>peer</I> <B>timers</B> <I>keepalive hold</I>
-</DL>
-
-Where <I>peer</I> specifies the BGP neighbour as either a hostname or
-IP address, <I>as</I> is the remote AS number and <I>keepalive</I>,
-<I>hold</I> are the timer values in seconds.
-
-<P>Named access-lists are configured using one of the commands:
-<DL>
-  <DD><B>ip access-list standard</B> <I>name</I>
-  <DD><B>ip access-list extended</B> <I>name</I>
-</DL>
-
-<P>Subsequent lines prefixed with <B>permit</B> or <B>deny</B>
-define the body of the access-list.  Standard access-list syntax:
-<DL>
-  <DD>{<B>permit</B>|<B>deny</B>}
-    {<I>host</I>|<I>source source-wildcard</I>|<B>any</B>}
-    [{<I>host</I>|<I>destination destination-wildcard</I>|<B>any</B>}]
-</DL>
-
-Extended access-lists:
-
-<DIV STYLE="margin-left: 4em; text-indent: -2em">
-  <P>{<B>permit</B>|<B>deny</B>} <B>ip</B>
-    {<I>host</I>|<I>source source-wildcard</I>|<B>any</B>}
-    {<I>host</I>|<I>destination destination-wildcard</I>|<B>any</B>} [<B>fragments</B>]
-  <P>{<B>permit</B>|<B>deny</B>} <B>udp</B>
-    {<I>host</I>|<I>source source-wildcard</I>|<B>any</B>}
-       [{<B>eq</B>|<B>neq</B>|<B>gt</B>|<B>lt</B>} <I>port</I>|<B>range</B> <I>from</I> <I>to</I>]
-    {<I>host</I>|<I>destination destination-wildcard</I>|<B>any</B>}
-       [{<B>eq</B>|<B>neq</B>|<B>gt</B>|<B>lt</B>} <I>port</I>|<B>range</B> <I>from</I> <I>to</I>]
-       [<B>fragments</B>]
-  <P>{<B>permit</B>|<B>deny</B>} <B>tcp</B>
-    {<I>host</I>|<I>source source-wildcard</I>|<B>any</B>}
-       [{<B>eq</B>|<B>neq</B>|<B>gt</B>|<B>lt</B>} <I>port</I>|<B>range</B> <I>from</I> <I>to</I>]
-    {<I>host</I>|<I>destination destination-wildcard</I>|<B>any</B>}
-       [{<B>eq</B>|<B>neq</B>|<B>gt</B>|<B>lt</B>} <I>port</I>|<B>range</B> <I>from</I> <I>to</I>]
-       [{<B>established</B>|{<B>match-any</B>|<B>match-all</B>}
-           {<B>+</B>|<B>-</B>}{<B>fin</B>|<B>syn</B>|<B>rst</B>|<B>psh</B>|<B>ack</B>|<B>urg</B>}
-           ...|<B>fragments</B>]
-</DIV>
-
-<H3 ID="users">users</H3>
-
-Usernames and passwords for the command-line interface are stored in
-this file.  The format is <I>username</I><B>:</B><I>password</I> where
-<I>password</I> may either by plain text, an MD5 digest (prefixed by
-<B>$1</B><I>salt</I><B>$</B>) or a DES password, distinguished from
-plain text by the prefix <B>{crypt}</B>.<P>
-
-The username <B>enable</B> has a special meaning and is used to set
-the enable password.<P>
-
-<B>Note:</B> If this file doesn't exist, then anyone who can get to
-port 23 will be allowed access without a username / password.<P>
-
-<H3 ID="ip-pool">ip_pool</H3>
-
-This file is used to configure the IP address pool which user
-addresses are assigned from.  This file should contain either an IP
-address or a CIDR network per line.  e.g.:<P>
-
-<PRE>
-    192.168.1.1
-    192.168.1.2
-    192.168.1.3
-    192.168.4.0/24
-    172.16.0.0/16
-    10.0.0.0/8
-</PRE>
-
-Keep in mind that l2tpns can only handle 65535 connections per
-process, so don't put more than 65535 IP addresses in the
-configuration file.  They will be wasted.
-
-<H3 ID="build-garden">build-garden</H3>
-
-The garden plugin on startup creates a NAT table called "garden" then
-sources the <B>build-garden</B> script to populate that table.  All
-packets from gardened users will be sent through this table.  Example:
-
-<PRE>
-    iptables -t nat -A garden -p tcp -m tcp --dport 25 -j DNAT --to 192.168.1.1
-    iptables -t nat -A garden -p udp -m udp --dport 53 -j DNAT --to 192.168.1.1
-    iptables -t nat -A garden -p tcp -m tcp --dport 53 -j DNAT --to 192.168.1.1
-    iptables -t nat -A garden -p tcp -m tcp --dport 80 -j DNAT --to 192.168.1.1
-    iptables -t nat -A garden -p tcp -m tcp --dport 110 -j DNAT --to 192.168.1.1
-    iptables -t nat -A garden -p tcp -m tcp --dport 443 -j DNAT --to 192.168.1.1
-    iptables -t nat -A garden -p icmp -m icmp --icmp-type echo-request -j DNAT --to 192.168.1.1
-    iptables -t nat -A garden -p icmp -j ACCEPT
-    iptables -t nat -A garden -j DROP
-</PRE>
-
-<H2 ID="ControllingtheProcess">Controlling the Process</H2>
-
-A running l2tpns process can be controlled in a number of ways.  The primary
-method of control is by the Command-Line Interface (CLI).<P>
-
-You can also remotely send commands to modules via the nsctl client
-provided.<P>
-
-Also, there are a number of signals that l2tpns understands and takes action
-when it receives them.
-
-<H3 ID="Command-LineInterface">Command-Line Interface</H3>
-
-You can access the command line interface by telnet'ing to port 23. 
-There is no IP address restriction, so it's a good idea to firewall
-this port off from anyone who doesn't need access to it.  See
-<A HREF="#users">users</A> for information on restricting access based
-on a username and password.<P>
-
-The CLI gives you real-time control over almost everything in
-the process.  The interface is designed to look like a Cisco
-device, and supports things like command history, line editing and
-context sensitive help.  This is provided by linking with the
-<A HREF="http://sourceforge.net/projects/libcli">libcli</A>
-library.  Some general documentation of the interface is
-<A HREF="http://sourceforge.net/docman/display_doc.php?docid=20501&group_id=79019">
-here</A>.<P>
-
-After you have connected to the telnet port (and perhaps logged in), you
-will be presented with a <I>hostname</I><B>&gt;</B> prompt.<P>
-
-Enter <EM>help</EM> to get a list of possible commands.  A brief
-overview of the more important commands follows:
-
-<UL>
-<LI><B>show session</B><BR>
-Without specifying a session ID, this will list all tunnels currently
-connected.  If you specify a session ID, you will be given all
-information on a single tunnel.  Note that the full session list can
-be around 185 columns wide, so you should probably use a wide terminal
-to see the list properly.<P>
-The columns listed in the overview are:
-<TABLE>
-       <TR><TD><B>SID</B></TD><TD>Session ID</TD></TR>
-       <TR><TD><B>TID</B></TD><TD>Tunnel ID - Use with <EM>show tunnel tid</EM></TD></TR>
-       <TR><TD><B>Username</B></TD><TD>The username given in the PPP
-       authentication.  If this is *, then LCP authentication has not
-       completed.</TD></TR>
-       <TR><TD><B>IP</B></TD><TD>The IP address given to the session.  If
-       this is 0.0.0.0, LCP negotiation has not completed.</TD></TR>
-       <TR><TD><B>I</B></TD><TD>Intercept - Y or N depending on whether the
-       session is being snooped.  See <EM>snoop</EM>.</TD></TR>
-       <TR><TD><B>T</B></TD><TD>Throttled - Y or N if the session is
-       currently throttled.  See <EM>throttle</EM>.</TD></TR>
-       <TR><TD><B>G</B></TD><TD>Walled Garden - Y or N if the user is
-       trapped in the walled garden.  This field is present even if the
-       garden module is not loaded.</TD></TR>
-       <TR><TD><B>opened</B></TD><TD>The number of seconds since the
-       session started</TD></TR>
-       <TR><TD><B>downloaded</B></TD><TD>Number of bytes downloaded by the user</TD></TR>
-       <TR><TD><B>uploaded</B></TD><TD>Number of bytes uploaded by the user</TD></TR>
-       <TR><TD><B>idle</B></TD><TD>The number of seconds since traffic was
-       detected on the session</TD></TR>
-       <TR><TD><B>LAC</B></TD><TD>The IP address of the LAC the session is
-       connected to.</TD></TR>
-       <TR><TD><B>CLI</B></TD><TD>The Calling-Line-Identification field
-       provided during the session setup.  This field is generated by the
-       LAC.</TD></TR>
-</TABLE>
-<P>
-</LI>
-
-<LI><B>show users</B><BR>
-With no arguments, display a list of currently connected users.  If an
-argument is given, the session details for the given username are
-displayed.
-</LI>
-
-<LI><B>show tunnel</B><BR>
-This will show all the open tunnels in a summary, or detail on a single
-tunnel if you give a tunnel id.<P>
-The columns listed in the overview are:
-<TABLE>
-       <TR><TD><B>TID</B></TD><TD>Tunnel ID</TD></TR>
-       <TR><TD><B>Hostname</B></TD><TD>The hostname for the tunnel as
-       provided by the LAC.  This has no relation to DNS, it is just
-       a text field.</TD></TR>
-       <TR><TD><B>IP</B></TD><TD>The IP address of the LAC</TD></TR>
-       <TR><TD><B>State</B></TD><TD>Tunnel state - Free, Open, Dieing,
-       Opening</TD></TR>
-       <TR><TD><B>Sessions</B></TD><TD>The number of open sessions on the
-       tunnel</TD></TR>
-</TABLE>
-<P>
-</LI>
-
-<LI><B>show pool</B><BR>
-Displays the current IP address pool allocation.  This will only display
-addresses that are in use, or are reserved for re-allocation to a
-disconnected user.<P>
-If an address is not currently in use, but has been used, then in the User
-column the username will be shown in square brackets, followed by the time
-since the address was used:
-<PRE>
-IP Address      Used  Session User
-192.168.100.6     N           [joe.user] 1548s
-</PRE>
-<P>
-</LI>
-
-<LI><B>show radius</B><BR>
-Show a summary of the in-use RADIUS sessions.  This list should not be very
-long, as RADIUS sessions should be cleaned up as soon as they are used.  The
-columns listed are:
-<TABLE>
-       <TR><TD><B>Radius</B></TD><TD>The ID of the RADIUS request.  This is
-       sent in the packet to the RADIUS server for identification.</TD></TR>
-       <TR><TD><B>State</B></TD><TD>The state of the request - WAIT, CHAP,
-       AUTH, IPCP, START, STOP, NULL.</TD></TR>
-       <TR><TD><B>Session</B></TD><TD>The session ID that this RADIUS
-       request is associated with</TD></TR>
-       <TR><TD><B>Retry</B></TD><TD>If a response does not appear to the
-       request, it will retry at this time.  This is a unix timestamp.</TD></TR>
-       <TR><TD><B>Try</B></TD><TD>Retry count.  The RADIUS request is
-       discarded after 3 retries.</TD></TR>
-</TABLE>
-<P>
-</LI>
-
-<LI><B>show running-config</B><BR>
-This will list the current running configuration.  This is in a format that
-can either be pasted into the configuration file, or run directly at the
-command line.
-<P>
-</LI>
-
-<LI><B>show counters</B><BR>
-Internally, counters are kept of key values, such as bytes and packets
-transferred, as well as function call counters.  This function displays all
-these counters, and is probably only useful for debugging.<P>
-You can reset these counters by running <EM>clear counters</EM>.
-<P>
-</LI>
-
-<LI><B>show cluster</B><BR>
-Show cluster status.  Shows the cluster state for this server
-(Master/Slave), information about known peers and (for slaves) the
-master IP address, last packet seen and up-to-date status.<P>
-See <A HREF="#Clustering">Clustering</A> for more information.
-<P>
-</LI>
-
-<LI><B>write memory</B><BR>
-This will write the current running configuration to the config file
-<B>startup-config</B>, which will be run on a restart.
-<P>
-</LI>
-
-<LI><B>snoop</B><BR>
-You must specify a username, IP address and port.  All packets for the
-current session for that username will be forwarded to the given
-host/port.  Specify <EM>no snoop username</EM> to disable interception
-for the session.<P>
-
-If you want interception to be permanent, you will have to modify the RADIUS
-response for the user.  See <A HREF="#Interception">Interception</A>.
-<P>
-</LI>
-
-<LI><B>throttle</B><BR>
-You must specify a username, which will be throttled for the current
-session.  Specify <EM>no throttle username</EM> to disable throttling
-for the current session.<P>
-
-If you want throttling to be permanent, you will have to modify the
-RADIUS response for the user.  See <A HREF="#Throttling">Throttling</A>.
-<P>
-</LI>
-
-<LI><B>drop session</B><BR>
-This will cleanly disconnect a session.  You must specify a session id, which
-you can get from <EM>show session</EM>.  This will send a disconnect message
-to the remote end.
-<P>
-</LI>
-
-<LI><B>drop tunnel</B><BR>
-This will cleanly disconnect a tunnel, as well as all sessions on that
-tunnel.  It will send a disconnect message for each session individually, and
-after 10 seconds it will send a tunnel disconnect message.
-<P>
-</LI>
-
-<LI><B>uptime</B><BR>
-This will show how long the l2tpns process has been running, and the current
-bandwidth utilization:
-<PRE>
-17:10:35 up 8 days, 2212 users, load average: 0.21, 0.17, 0.16
-Bandwidth: UDP-ETH:6/6  ETH-UDP:13/13  TOTAL:37.6   IN:3033 OUT:2569
-</PRE>
-The bandwidth line contains 4 sets of values.<BR>
-UDP-ETH is the current bandwidth going from the LAC to the ethernet
-(user uploads), in mbits/sec.<BR>
-ETH-UDP is the current bandwidth going from ethernet to the LAC (user
-downloads).<BR>
-TOTAL is the total aggregate bandwidth in mbits/s.<BR>
-IN and OUT are packets/per-second going between UDP-ETH and ETH-UDP.
-<P>
-These counters are updated every second.
-<P>
-</LI>
-
-<LI><B>configure terminal</B><BR>
-Enter configuration mode.  Use <EM>exit</EM> or ^Z to exit this mode. 
-The following commands are valid in this mode:<P>
-</LI>
-
-<LI><B>load plugin</B><BR>
-Load a plugin.  You must specify the plugin name, and it will search in
-/usr/lib/l2tpns for <EM>plugin</EM>.so.  You can unload a loaded plugin with
-<EM>remove plugin</EM>.
-<P>
-</LI>
-
-<LI><B>set</B><BR>
-Set a configuration variable.  You must specify the variable name, and
-the value.  If the value contains any spaces, you should quote the
-value with double (") or single (') quotes.<P>
-
-You can set any <A HREF="#startup-config">startup-config</A> value in
-this way, although some may require a restart to take effect.<P>
-</LI>
-</UL>
-
-<H3 ID="nsctl">nsctl</H3>
-
-nsctl allows messages to be passed to plugins.<P>
-
-Arguments are <EM>command</EM> and optional <EM>args</EM>.  See
-<STRONG>nsctl</STRONG>(8) for more details.<P>
-
-Built-in command are <EM>load_plugin</EM>, <EM>unload_plugin</EM> and
-<EM>help</EM>.  Any other commands are passed to plugins for processing.
-
-<H3 ID="Signals">Signals</H3>
-
-While the process is running, you can send it a few different signals, using
-the kill command.
-<PRE>
-killall -HUP l2tpns
-</PRE>
-
-The signals understood are:
-<DL>
-<DT>SIGHUP</DT><DD>Reload the config from disk and re-open log file.</DD>
-<DT>SIGTERM, SIGINT</DT><DD>Stop process.  Tunnels and sessions are not
-terminated.  This signal should be used to stop l2tpns on a
-<A HREF="#Clustering">cluster node</A> where there are other machines to
-continue handling traffic.</DD>
-<DT>SIGQUIT</DT><DD>Shut down tunnels and sessions, exit process when
-complete.</DD>
-</DL>
-
-<H2 ID="Throttling">Throttling</H2>
-
-l2tpns contains support for slowing down user sessions to whatever speed you
-desire.  You must first enable the global setting <EM>throttle_speed</EM>
-before this will be activated.<P>
-
-If you wish a session to be throttled permanently, you should set the
-Vendor-Specific RADIUS value <B>Cisco-Avpair="throttle=yes"</B>, which
-will be handled by the <EM>autothrottle</EM> module.<P>
-
-Otherwise, you can enable and disable throttling an active session using
-the <EM>throttle</EM> CLI command.<P>
-
-<H2 ID="Interception">Interception</H2>
-
-You may have to deal with legal requirements to be able to intercept a
-user's traffic at any time.  l2tpns allows you to begin and end interception
-on the fly, as well as at authentication time.<P>
-
-When a user is being intercepted, a copy of every packet they send and
-receive will be sent wrapped in a UDP packet to the IP address and port set
-in the <EM>snoop_host</EM> and <EM>snoop_port</EM> configuration
-variables.<P>
-
-The UDP packet contains just the raw IP frame, with no extra headers.<P>
-
-To enable interception on a connected user, use the <EM>snoop username</EM>
-and <EM>no snoop username</EM> CLI commands.  These will enable interception
-immediately.<P>
-
-If you wish the user to be intercepted whenever they reconnect, you will
-need to modify the RADIUS response to include the Vendor-Specific value
-<B>Cisco-Avpair="intercept=yes"</B>.  For this feature to be enabled,
-you need to have the <EM>autosnoop</EM> module loaded.<P>
-
-<H2 ID="Authentication">Authentication</H2>
-
-Whenever a session connects, it is not fully set up until authentication is
-completed.  The remote end must send a PPP CHAP or PPP PAP authentication
-request to l2tpns.<P>
-
-This request is sent to the RADIUS server, which will hopefully respond with
-Auth-Accept or Auth-Reject.<P>
-
-If Auth-Accept is received, the session is set up and an IP address is
-assigned.  The RADIUS server can include a Framed-IP-Address field in the
-reply, and that address will be assigned to the client.  It can also include
-specific DNS servers, and a Framed-Route if that is required.<P>
-
-If Auth-Reject is received, then the client is sent a PPP AUTHNAK packet,
-at which point they should disconnect.  The exception to this is when the
-walled garden module is loaded, in which case the user still receives the
-PPP AUTHACK, but their session is flagged as being a garden'd user, and they
-should not receive any service.<P>
-
-The RADIUS reply can also contain a Vendor-Specific attribute called
-Cisco-Avpair.  This field is a freeform text field that most Cisco
-devices understand to contain configuration instructions for the session.  In
-the case of l2tpns it is expected to be of the form
-<PRE>
-key=value,key2=value2,key3=value3,key<EM>n</EM>=<EM>value</EM>
-</PRE>
-
-Each key-value pair is separated and passed to any modules loaded.  The
-<EM>autosnoop</EM> and <EM>autothrottle</EM> understand the keys
-<EM>intercept</EM> and <EM>throttle</EM> respectively.  For example, to have
-a user who is to be throttled and intercepted, the Cisco-Avpair value should
-contain:
-<PRE>
-intercept=yes,throttle=yes
-</PRE>
-
-<H2 ID="Plugins">Plugins</H2>
-
-So as to make l2tpns as flexible as possible (I know the core code is pretty
-difficult to understand), it includes a plugin API, which you can use to
-hook into certain events.<P>
-
-There are a few example modules included - autosnoop, autothrottle and
-garden.<P>
-
-When an event happens that has a hook, l2tpns looks for a predefined
-function name in every loaded module, and runs them in the order the modules
-were loaded.<P>
-
-The function should return <B>PLUGIN_RET_OK</B> if it is all OK.  If it returns
-<B>PLUGIN_RET_STOP</B>, then it is assumed to have worked, but that no further
-modules should be run for this event.<P>
-A return of <B>PLUGIN_RET_ERROR</B> means that this module failed, and
-no further processing should be done for this event.  <EM>Use this with care.</EM>
-
-Every event function called takes a specific structure named
-param_<EM>event</EM>, which varies in content with each event.  The
-function name for each event will be <B>plugin_<EM>event</EM></B>,
-so for the event <EM>timer</EM>, the function declaration should look like:
-<PRE>
-int plugin_timer(struct param_timer *data);
-</PRE>
-
-A list of the available events follows, with a list of all the fields in the
-supplied structure:
-<TABLE CELLSPACING=0 CELLPADDING=0><TR BGCOLOR=LIGHTGREEN><TD>
-<TABLE CELLSPACING=1 CELLPADDING=3>
-       <TR BGCOLOR=LIGHTGREEN><TH><B>Event</B></TH><TH><B>Description</B></TH><TH><B>Parameters</B></TH></TR>
-       <TR VALIGN=TOP BGCOLOR=WHITE><TD><B>pre_auth</B></TD>
-               <TD>This is called after a RADIUS response has been
-               received, but before it has been processed by the
-               code.  This will allow you to modify the response in
-               some way.
-               </TD>
-               <TD>
-               <DL>
-                       <DT>t<DD>Tunnel
-                       <DT>s<DD>Session
-                       <DT>username
-                       <DT>password
-                       <DT>protocol<DD>0xC023 for PAP, 0xC223 for CHAP
-                       <DT>continue_auth<DD>Set to 0 to stop processing authentication modules
-               </DL>
-               </TD>
-       </TR>
-       <TR VALIGN=TOP BGCOLOR=WHITE><TD><B>post_auth</B></TD>
-               <TD>This is called after a RADIUS response has been
-               received, and the basic checks have been performed.  This
-               is what the garden module uses to force authentication
-               to be accepted.
-               </TD>
-               <TD>
-               <DL>
-                       <DT>t<DD>Tunnel
-                       <DT>s<DD>Session
-                       <DT>username
-                       <DT>auth_allowed<DD>This is already set to true or
-                       false depending on whether authentication has been
-                       allowed so far.  You can set this to 1 or 0 to force
-                       allow or disallow authentication
-                       <DT>protocol<DD>0xC023 for PAP, 0xC223 for CHAP
-               </DL>
-               </TD>
-       </TR>
-       <TR VALIGN=TOP BGCOLOR=WHITE><TD><B>packet_rx</B></TD>
-               <TD>This is called whenever a session receives a
-               packet.  <FONT COLOR=RED>Use this sparingly, as this will
-               seriously slow down the system.</FONT>
-               </TD>
-               <TD>
-               <DL>
-                       <DT>t<DD>Tunnel
-                       <DT>s<DD>Session
-                       <DT>buf<DD>The raw packet data
-                       <DT>len<DD>The length of buf
-               </DL>
-               </TD>
-       </TR>
-       <TR VALIGN=TOP BGCOLOR=WHITE><TD><B>packet_tx</B></TD>
-               <TD>This is called whenever a session sends a
-               packet.  <FONT COLOR=RED>Use this sparingly, as this will
-               seriously slow down the system.</FONT>
-               </TD>
-               <TD>
-               <DL>
-                       <DT>t<DD>Tunnel
-                       <DT>s<DD>Session
-                       <DT>buf<DD>The raw packet data
-                       <DT>len<DD>The length of buf
-               </DL>
-               </TD>
-       </TR>
-       <TR VALIGN=TOP BGCOLOR=WHITE><TD><B>timer</B></TD>
-               <TD>This is run every second, no matter what is happening.
-               This is called from a signal handler, so make sure anything
-               you do is reentrant.
-               </TD>
-               <TD>
-               <DL>
-                       <DT>time_now<DD>The current unix timestamp
-               </DL>
-               </TD>
-       </TR>
-       <TR VALIGN=TOP BGCOLOR=WHITE><TD><B>new_session</B></TD>
-               <TD>This is called after a session is fully set up.  The
-               session is now ready to handle traffic.
-               </TD>
-               <TD>
-               <DL>
-                       <DT>t<DD>Tunnel
-                       <DT>s<DD>Session
-               </DL>
-               </TD>
-       </TR>
-       <TR VALIGN=TOP BGCOLOR=WHITE><TD><B>kill_session</B></TD>
-               <TD>This is called when a session is about to be shut down.
-               This may be called multiple times for the same session.
-               </TD>
-               <TD>
-               <DL>
-                       <DT>t<DD>Tunnel
-                       <DT>s<DD>Session
-               </DL>
-               </TD>
-       </TR>
-       <TR VALIGN=TOP BGCOLOR=WHITE><TD><B>radius_response</B></TD>
-               <TD>This is called whenever a RADIUS response includes a
-               Cisco-Avpair value.  The value is split up into
-               <EM>key=value</EM> pairs, and each is processed through all
-               modules.
-               </TD>
-               <TD>
-               <DL>
-                       <DT>t<DD>Tunnel
-                       <DT>s<DD>Session
-                       <DT>key
-                       <DT>value
-               </DL>
-               </TD>
-       </TR>
-       <TR VALIGN=TOP BGCOLOR=WHITE><TD><B>radius_reset</B></TD>
-               <TD>This is called whenever a RADIUS CoA request is
-               received to reset any options to default values before
-               the new values are applied.
-               </TD>
-               <TD>
-               <DL>
-                       <DT>t<DD>Tunnel
-                       <DT>s<DD>Session
-               </DL>
-               </TD>
-       </TR>
-       <TR VALIGN=TOP BGCOLOR=WHITE><TD><B>control</B></TD>
-               <TD>This is called in whenever a nsctl packet is received.
-               This should handle the packet and form a response if
-               required.
-               </TD>
-               <TD>
-               <DL>
-                       <DT>iam_master<DD>Cluster master status
-                       <DT>argc<DD>The number of arguments
-                       <DT>argv<DD>Arguments
-                       <DT>response<DD>Return value: NSCTL_RES_OK or NSCTL_RES_ERR
-                       <DT>additional<DD>Extended response text
-               </DL>
-               </TD>
-       </TR>
-</TABLE>
-</TD></TR></TABLE>
-
-<H2 ID="WalledGarden">Walled Garden</H2>
-
-Walled Garden is implemented so that you can provide perhaps limited service
-to sessions that incorrectly authenticate.<P>
-
-Whenever a session provides incorrect authentication, and the
-RADIUS server responds with Auth-Reject, the walled garden module
-(if loaded) will force authentication to succeed, but set the flag
-<EM>garden</EM> in the session structure, and adds an iptables rule to
-the <B>garden_users</B> chain to force all packets for the session's IP
-address to traverse the <B>garden</B> chain.<P>
-
-This doesn't <EM>just work</EM>.  To set this all up, you will to
-setup the <B>garden</B> nat table with the
-<A HREF="#build-garden">build-garden</A> script with rules to limit
-user's traffic.  For example, to force all traffic except DNS to be
-forwarded to 192.168.1.1, add these entries to your
-<EM>build-garden</EM>:
-<PRE>
-iptables -t nat -A garden -p tcp --dport ! 53 -j DNAT --to 192.168.1.1
-iptables -t nat -A garden -p udp --dport ! 53 -j DNAT --to 192.168.1.1
-</PRE>
-
-l2tpns will add entries to the garden_users chain as appropriate.<P>
-
-You can check the amount of traffic being captured using the following
-command:
-<PRE>
-iptables -t nat -L garden -nvx
-</PRE>
-
-<H2 ID="Filtering">Filtering</H2>
-
-Sessions may be filtered by specifying <B>Filter-Id</B> attributes in
-the RADIUS reply.  <I>filter</I>.<B>in</B> specifies that the named
-access-list <I>filter</I> should be applied to traffic from the
-customer, <I>filter</I>.<B>out</B> specifies a list for traffic to the
-customer.
-
-<H2 ID="Clustering">Clustering</H2>
-
-An l2tpns cluster consists of of one* or more servers configured with
-the same configuration, notably the multicast <B>cluster_address</B>.<P>
-
-*A stand-alone server is simply a degraded cluster.<P>
-
-Initially servers come up as cluster slaves, and periodically (every
-<B>cluster_hb_interval</B>/10 seconds) send out ping packets
-containing the start time of the process to the multicast
-<B>cluster_address</B>.<P>
-
-A cluster master sends heartbeat rather than ping packets, which
-contain those session and tunnel changes since the last heartbeat.<P>
-
-When a slave has not seen a heartbeat within
-<B>cluster_hb_timeout</B>/10 seconds it "elects" a new master by
-examining the list of peers it has seen pings from and determines
-which of these and itself is the "best" candidate to be master. 
-"Best" in this context means the server with the highest uptime (the
-highest IP address is used as a tie-breaker in the case of equal
-uptimes).<P>
-
-After discovering a master, and determining that it is up-to-date (has
-seen an update for all in-use sessions and tunnels from heartbeat
-packets) will raise a route (see <A HREF="#Routing">Routing</A>) for
-the <B>bind_address</B> and for all addresses/networks in
-<B>ip_pool</B>.  Any packets recieved by the slave which would alter
-the session state, as well as packets for throttled or gardened
-sessions are forwarded to the master for handling.  In addition, byte
-counters for session traffic are periodically forwarded.<P>
-
-A master, when determining that it has at least one up-to-date slave
-will drop all routes (raising them again if all slaves disappear) and
-subsequently handle only packets forwarded to it by the slaves.<P>
-
-<H2 ID="Routing">Routing</H2>
-If you are running a single instance, you may simply statically route
-the IP pools to the <B>bind_address</B> (l2tpns will send a gratuitous
-arp).<P>
-
-For a cluster, configure the members as BGP neighbours on your router
-and configure multi-path load-balancing.  Cisco uses "maximum-paths
-ibgp" for IBGP.  If this is not supported by your IOS revision, you
-can use "maximum-paths" (which works for EBGP) and set
-<B>as_number</B> to a private value such as 64512.<P>
-
-<H2 ID="Performance">Performance</H2>
-
-Performance is great.<P>
-
-I'd like to include some pretty graphs here that show a linear performance
-increase, with no impact by number of connected sessions.<P>
-
-That's really what it looks like.<P>
-
-<BR>
-David Parrish<BR>
-<A HREF="mailto:l2tpns-users@lists.sourceforge.net?subject=L2TPNS%20Documentation">l2tpns-users@lists.sourceforge.net</A>
-</BODY>
-</HTML>
diff --git a/Docs/manual/manual.xml b/Docs/manual/manual.xml
new file mode 100644 (file)
index 0000000..cb26b54
--- /dev/null
@@ -0,0 +1,2150 @@
+<?xml version="1.0"?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+    "http://docbook.org/xml/4.4/docbookx.dtd">
+
+<article>
+  <articleinfo>
+    <title>L2TPNS Manual</title>
+  </articleinfo>
+
+  <sect1 id="overview">
+    <title>Overview</title>
+    <para>
+      <command>l2tpns</command> is half of a complete L2TP
+      implementation.  It supports only the LNS side of the
+      connection.
+    </para>
+
+    <para>
+      L2TP (Layer 2 Tunneling Protocol) is designed to allow any layer
+      2 protocol (e.g.  Ethernet, PPP) to be tunneled over an IP
+      connection.  <command>l2tpns</command> implements PPP over L2TP
+      only.
+    </para>
+
+    <para>
+      There are a couple of other L2TP implementations, of which
+      <ulink url="http://sourceforge.net/projects/l2tpd">l2tpd</ulink>
+      is probably the most popular.  l2tpd also will handle being
+      either end of a tunnel, and is a lot more configurable than
+      <command>l2tpns</command>.  However, due to the way it works, it
+      is nowhere near as scalable.
+    </para>
+
+    <para>
+      <command>l2tpns</command> uses the TUN/TAP interface provided by
+      the Linux kernel to receive and send packets.  Using some packet
+      manipulation it doesn't require a single interface per
+      connection, as l2tpd does.
+    </para>
+
+    <para>
+      This allows it to scale extremely well to very high loads and
+      very high numbers of connections.
+    </para>
+
+    <para>
+      It also has a plugin architecture which allows custom code to be
+      run during processing.  An example of this is in the walled
+      garden module included.
+    </para>
+  </sect1>
+
+  <sect1 id="installation">
+    <title>Installation</title>
+    <sect2 id="installation-requirements">
+      <title>Requirements</title>
+      <itemizedlist>
+       <listitem>
+         <para>
+           Linux kernel version 2.4 or above, with the Tun/Tap
+           interface either compiled in, or as a module.
+         </para>
+       </listitem>
+
+       <listitem>
+         <para>
+           libcli 1.8.5 or greater.  You can get this from
+           <ulink url="http://sourceforge.net/projects/libcli">
+           SourceForge</ulink>
+         </para>
+       </listitem>
+      </itemizedlist>
+    </sect2>
+
+    <sect2 id="installation-compile">
+      <title>Compiling</title>
+      <para>
+       You can generally get away with just running
+       <command>make</command> from the source directory.  This will
+       compile the daemon, associated tools and any modules shipped
+       with the distribution.
+      </para>
+    </sect2>
+
+    <sect2 id="installation-install">
+      <title>Installing</title>
+      <para>
+       After you have successfully compiled everything, run
+       <userinput>make install</userinput> to install it.  By
+       default, the binaries are installed into
+       <filename>/usr/sbin</filename>, the configuration into
+       <filename>/etc/l2tpns</filename>, and the modules into
+       <filename>/usr/lib/l2tpns</filename>.
+      </para>
+
+      <para>
+       You will definately need to edit the configuration files
+       before you start.  See <xref linkend="configuration"/> for
+       more information.
+      </para>
+    </sect2>
+
+    <sect2 id="installation-run">
+      <title>Running</title>
+      <para>
+       You only need to run <filename>/usr/sbin/l2tpns</filename> as
+       root to start it.  It does not normally detach to a daemon
+       process (see the <option>-d</option> option), so you should
+       perhaps run it from <command>init</command>.
+      </para>
+
+      <para>
+       By default there is no log destination set, so all log
+       messages will go to stdout.
+      </para>
+    </sect2>
+  </sect1>
+
+  <sect1 id="configuration">
+    <title>Configuration</title>
+    <para>
+      All configuration of the software is done from the files
+      installed into <filename>/etc/l2tpns</filename>.
+    </para>
+
+    <sect2 id="config-startup">
+      <title><filename>startup-config</filename></title>
+      <para>
+       This is the main configuration file for
+       <command>l2tpns</command>.  The format of the file is a list
+       of commands that can be run through the command-line
+       interface.  This file can also be written directly by the
+       <command>l2tpns</command> process if a user runs the
+       <userinput>write memory</userinput> command, so any comments
+       will be lost.  However if your policy is not to write the
+       config by the program, then feel free to comment the file with
+       a <literal>#</literal> or <literal>!</literal> at the
+       beginning of the line.
+      </para>
+
+      <para>
+       A list of the possible configuration directives follows.  Each
+       of these should be set by a line like:
+<synopsis>
+set configstring "value"
+set ipaddress 192.168.1.1
+set boolean true
+</synopsis>
+      </para>
+
+      <variablelist>
+       <varlistentry>
+         <term><literal>debug</literal> (int)</term>
+         <listitem>
+           <para>
+             Sets the level of messages that will be written to the
+             log file.  The value should be between 0 and 5, with 0
+             being no debugging, and 5 being the highest.  A rough
+             description of the levels is:
+
+             <variablelist>
+               <varlistentry>
+                 <term><constant>0</constant>: Critical Errors</term>
+                 <listitem>
+                   <para>Things are probably broken</para>
+                 </listitem>
+               </varlistentry>
+
+               <varlistentry>
+                 <term><constant>1</constant>: Errors</term>
+                 <listitem>
+                   <para>
+                     Things might have gone wrong, but probably will
+                     recover
+                   </para>
+                 </listitem>
+               </varlistentry>
+
+               <varlistentry>
+                 <term><constant>2</constant>: Warnings</term>
+                 <listitem>
+                   <para>
+                     Just in case you care what is not quite perfect
+                   </para>
+                 </listitem>
+               </varlistentry>
+
+               <varlistentry>
+                 <term><constant>3</constant>: Information</term>
+                 <listitem>
+                   <para>Parameters of control packets</para>
+                 </listitem>
+               </varlistentry>
+
+               <varlistentry>
+                 <term><constant>4</constant>: Calls</term>
+                 <listitem>
+                   <para>For tracing the execution of the code</para>
+                 </listitem>
+               </varlistentry>
+
+               <varlistentry>
+                 <term><constant>5</constant>: Packets</term>
+                 <listitem>
+                   <para>
+                     Everything, including a hex dump of all packets
+                     processed...  probably twice
+                   </para>
+                 </listitem>
+               </varlistentry>
+             </variablelist>
+           </para>
+
+           <para>
+             Note that the higher you set the debugging level, the
+             slower the program will run.  Also, at level 5 a
+             <emphasis>lot</emphasis> of information will be logged.
+             This should only ever be used for working out why it
+             doesn't work at all.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>log_file</literal> (string)</term>
+         <listitem>
+           <para>
+             This will be where all logging and debugging information
+             is written to.  This may be either a filename, such as
+             <filename>/var/log/l2tpns</filename>, or the special
+             magic string
+             <literal>syslog:</literal><replaceable>facility</replaceable>,
+             where <replaceable>facility</replaceable> is any one of
+             the syslog logging facilities, such as
+             <literal>local5</literal>.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>pid_file</literal> (string)</term>
+         <listitem>
+           <para>
+             If set, the process id will be written to the specified
+             file.  The value must be an absolute path.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>random_device</literal> (string)</term>
+         <listitem>
+           <para>
+             Path to random data source (default
+             <filename>/dev/urandom</filename>).  Use "" to use the
+             rand() library function.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>l2tp_secret</literal> (string)</term>
+         <listitem>
+           <para>
+             The secret used by <command>l2tpns</command> for
+             authenticating tunnel request.  Must be the same as the
+             LAC, or authentication will fail.  Only actually be used
+             if the LAC requests authentication.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>l2tp_mtu</literal> (int)</term>
+         <listitem>
+           <para>
+             MTU of interface for L2TP traffic (default:
+             <literal>1500</literal>).  Used to set link MRU and
+             adjust TCP MSS.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>ppp_restart_time</literal> (int)</term>
+         <term><literal>ppp_max_configure</literal> (int)</term>
+         <term><literal>ppp_max_failure</literal> (int)</term>
+         <listitem>
+           <para>
+             PPP counter and timer values, as described in &sect;4.1
+             of <ulink url="ftp://ftp.rfc-editor.org/in-notes/rfc1661.txt">
+             RFC1661</ulink>.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>primary_dns</literal> (ip address)</term>
+         <term><literal>econdary_dns</literal> (ip address)</term>
+         <listitem>
+           <para>
+             Whenever a PPP connection is established, DNS servers
+             will be sent to the user, both a primary and a
+             secondary.  If either is set to 0.0.0.0, then that one
+             will not be sent.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>primary_radius</literal> (ip address)</term>
+         <term><literal>secondary_radius</literal> (ip address)</term>
+         <listitem>
+           <para>
+             Sets the RADIUS servers used for both authentication and
+             accounting.  If the primary server does not respond,
+             then the secondary RADIUS server will be tried.
+
+             <note>
+               <para>
+                 In addition to the source IP address and identifier,
+                 the RADIUS server <emphasis>must</emphasis> include
+                 the source port when detecting duplicates to supress
+                 (in order to cope with a large number of sessions
+                 comming on-line simultaneously
+                 <command>l2tpns</command> uses a set of udp sockets,
+                 each with a seperate identifier).
+               </para>
+             </note>
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>primary_radius_port</literal> (short)</term>
+         <term><literal>secondary_radius_port</literal> (short)</term>
+         <listitem>
+           <para>
+             Sets the authentication ports for the primary and
+             secondary RADIUS servers.  The accounting port is one
+             more than the authentication port.  If no RADIUS ports
+             are given, the authentication port defaults to 1645, and
+             the accounting port to 1646.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>radius_accounting</literal> (boolean)</term>
+         <listitem>
+           <para>
+             If set to true, then RADIUS accounting packets will be
+             sent.  This means that a Start record will be sent when
+             the session is successfully authenticated, and a Stop
+             record will be sent when the session is closed.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>radius_interim</literal> (int)</term>
+         <listitem>
+           <para>
+             If <literal>radius_accounting</literal> is on, defines
+             the interval between sending of RADIUS interim
+             accounting records (in seconds).
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>radius_secret</literal> (string)</term>
+         <listitem>
+           <para>
+             This secret will be used in all RADIUS queries.  If this
+             is not set then RADIUS queries will fail.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>radius_authtypes</literal> (string)</term>
+         <listitem>
+           <para>
+             A comma separated list of supported RADIUS
+             authentication methods (<literal>pap</literal> or
+             <literal>chap</literal>), in order of preference
+             (default <literal>pap</literal>).
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>radius_dae_port</literal> (short)</term>
+         <listitem>
+           <para>
+             Port for DAE RADIUS (Packet of Death/Disconnect, Change
+             of Authorization) requests (default:
+             <literal>3799</literal>).
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>allow_duplicate_users</literal> (boolean)</term>
+         <listitem>
+           <para>
+             Allow multiple logins with the same username.  If false
+             (the default), any prior session with the same username
+             will be dropped when a new session is established.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>guest_account</literal> (string)</term>
+         <listitem>
+           <para>
+             Allow multiple logins matching this specific username.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>bind_address</literal> (ip address)</term>
+         <listitem>
+           <para>
+             When the tun interface is created, it is assigned the
+             address specified here.  If no address is given, 1.1.1.1
+             is used.  Packets containing user traffic should be
+             routed via this address if given, otherwise the primary
+             address of the machine.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>peer_address</literal> (ip address)</term>
+         <listitem>
+           <para>Address to send to clients as the default gateway.</para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>send_garp</literal> (boolean)</term>
+         <listitem>
+           <para>
+             Determines whether or not to send a gratuitous ARP for
+             the bind_address when the server is ready to handle
+             traffic (default:  <literal>true</literal>).  This value
+             is ignored if BGP is configured.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>throttle_speed</literal> (int)</term>
+         <listitem>
+           <para>
+             Sets the default speed (in kbits/s) which sessions will
+             be limited to.  If this is set to 0, then throttling
+             will not be used at all.  Note:  You can set this by the
+             CLI, but changes will not affect currently connected
+             users.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>throttle_buckets</literal> (int)</term>
+         <listitem>
+           <para>
+             Number of token buckets to allocate for throttling.
+             Each throttled session requires two buckets (in and
+             out).
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>accounting_dir</literal> (string)</term>
+         <listitem>
+           <para>
+             If set to a directory, then every 5 minutes the current
+             usage for every connected use will be dumped to a file
+             in this directory.  Each file dumped begins with a
+             header, where each line is prefixed by <code>#</code>.
+             Following the header is a single line for every
+             connected user, fields separated by a space.
+           </para>
+
+           <para>
+             The fields are username, ip, qos, uptxoctets,
+             downrxoctets.  The qos field is 1 if a standard user,
+             and 2 if the user is throttled.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>dump_speed</literal> (boolean)</term>
+         <listitem>
+           <para>
+             If set to true, then the current bandwidth utilization
+             will be logged every second.  Even if this is disabled,
+             you can see this information by running the
+             <userinput>uptime</userinput> command on the CLI.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>multi_read_count</literal> (int)</term>
+         <listitem>
+           <para>
+             Number of packets to read off each of the UDP and TUN
+             fds when returned as readable by select (default:  10).
+             Avoids incurring the unnecessary system call overhead of
+             select on busy servers.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>scheduler_fifo</literal> (boolean)</term>
+         <listitem>
+           <para>
+             Sets the scheduling policy for the
+             <command>l2tpns</command> process to
+             <constant>SCHED_FIFO</constant>.  This causes the kernel
+             to immediately preempt any currently running
+             <constant>SCHED_OTHER</constant> (normal) process in
+             favour of <command>l2tpns</command> when it becomes
+             runnable.  Ignored on uniprocessor systems.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>lock_pages</literal> (boolean)</term>
+         <listitem>
+           <para>
+             Keep all pages mapped by the <command>l2tpns</command>
+             process in memory.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>icmp_rate</literal> (int)</term>
+         <listitem>
+           <para>
+             Maximum number of host unreachable ICMP packets to send
+             per second.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>packet_limit</literal> (int)</term>
+         <listitem>
+           <para>
+             Maximum number of packets of downstream traffic to be
+             handled each tenth of a second per session.  If zero, no
+             limit is applied (default:  0).  Intended as a DoS
+             prevention mechanism and not a general throttling
+             control (packets are dropped, not queued).
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>cluster_address</literal> (ip address)</term>
+         <listitem>
+           <para>
+             Multicast cluster address (default: 239.192.13.13).
+             See <xref linkend="clustering"/> for more information.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>cluster_interface</literal> (string)</term>
+         <listitem>
+           <para>Interface for cluster packets (default: eth0)</para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>cluster_mcast_ttl</literal> (int)</term>
+         <listitem>
+           <para>TTL for multicast packets (default: 1).</para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>cluster_hb_interval</literal> (int)</term>
+         <listitem>
+           <para>
+             Interval in tenths of a second between cluster
+             heartbeat/pings.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>cluster_hb_timeout</literal> (int)</term>
+         <listitem>
+           <para>
+             Cluster heartbeat timeout in tenths of a second.  A new
+             master will be elected when this interval has been
+             passed without seeing a heartbeat from the master.
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>cluster_master_min_adv</literal> (int)</term>
+         <listitem>
+           <para>
+             Determines the minumum number of up to date slaves
+             required before the master will drop routes (default: 1).
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term><literal>ipv6_prefix</literal> (ipv6 address)</term>
+         <listitem>
+           <para>
+             Enable negotiation of IPv6.  This forms the the first 64
+             bits of the client allocated address.  The remaining 64
+             come from the allocated IPv4 address and 4 bytes of 0s.
+           </para>
+         </listitem>
+       </varlistentry>
+      </variablelist>
+
+      <sect3 id="config-startup-bgp">
+       <title>BGP</title>
+       <para>
+         BGP routing configuration is entered by the command:
+         <synopsis>router bgp <replaceable>as</replaceable></synopsis>
+         where <replaceable>as</replaceable> specifies the local AS
+         number.
+       </para>
+
+       <para>
+         Subsequent lines prefixed with
+         <synopsis>neighbour <replaceable>peer</replaceable></synopsis>
+         define the attributes of BGP neighhbours.  Valid commands
+         are:
+<synopsis>
+neighbour <replaceable>peer</replaceable> remote-as <replaceable>as</replaceable>
+neighbour <replaceable>peer</replaceable> timers <replaceable>keepalive hold</replaceable>
+</synopsis>
+       </para>
+
+       <para>
+         Where <replaceable>peer</replaceable> specifies the BGP
+         neighbour as either a hostname or IP address,
+         <replaceable>as</replaceable> is the remote AS number and
+         <replaceable>keepalive</replaceable>,
+         <replaceable>hold</replaceable> are the timer values in
+         seconds.
+       </para>
+      </sect3>
+
+      <sect3 id="config-startup-acl">
+       <title>Access Lists</title>
+       <para>
+         Named access-lists are configured using one of the commands:
+<synopsis>
+ip access-list standard <replaceable>name</replaceable>
+ip access-list extended <replaceable>name</replaceable>
+</synopsis>
+       </para>
+
+       <para>
+         Subsequent lines prefixed with <literal>permit</literal> or
+         <literal>deny</literal> define the body of the access-list.
+         Standard access-list syntax:
+       </para>
+
+       <para role="hanging-indent">
+         {<literal>permit</literal>|<literal>deny</literal>}
+         {<replaceable>host</replaceable>|<replaceable>source
+         source-wildcard</replaceable>|<literal>any</literal>}
+         [{<replaceable>host</replaceable>|<replaceable>destination
+         destination-wildcard</replaceable>|<literal>any</literal>}]
+       </para>
+
+       <para>Extended access-lists:</para>
+       <para role="hanging-indent">
+         {<literal>permit</literal>|<literal>deny</literal>}
+         <literal>ip</literal>
+         {<replaceable>host</replaceable>|<replaceable>source
+         source-wildcard</replaceable>|<literal>any</literal>}
+         {<replaceable>host</replaceable>|<replaceable>destination
+         destination-wildcard</replaceable>|<literal>any</literal>}
+         [<literal>fragments</literal>]
+       </para>
+
+       <para role="hanging-indent">
+         {<literal>permit</literal>|<literal>deny</literal>}
+         <literal>udp</literal>
+         {<replaceable>host</replaceable>|<replaceable>source
+         source-wildcard</replaceable>|<literal>any</literal>}
+         [{<literal>eq</literal>|<literal>neq</literal>|<literal>gt</literal>|<literal>lt</literal>}
+         <replaceable>port</replaceable>|<literal>range</literal>
+         <replaceable>from</replaceable>
+         <replaceable>to</replaceable>]
+         {<replaceable>host</replaceable>|<replaceable>destination
+         destination-wildcard</replaceable>|<literal>any</literal>}
+         [{<literal>eq</literal>|<literal>neq</literal>|<literal>gt</literal>|<literal>lt</literal>}
+         <replaceable>port</replaceable>|<literal>range</literal>
+         <replaceable>from</replaceable>
+         <replaceable>to</replaceable>]
+         [<literal>fragments</literal>]
+       </para>
+
+       <para role="hanging-indent">
+         {<literal>permit</literal>|<literal>deny</literal>}
+         <literal>tcp</literal>
+         {<replaceable>host</replaceable>|<replaceable>source
+         source-wildcard</replaceable>|<literal>any</literal>}
+         [{<literal>eq</literal>|<literal>neq</literal>|<literal>gt</literal>|<literal>lt</literal>}
+         <replaceable>port</replaceable>|<literal>range</literal>
+         <replaceable>from</replaceable>
+         <replaceable>to</replaceable>]
+         {<replaceable>host</replaceable>|<replaceable>destination
+         destination-wildcard</replaceable>|<literal>any</literal>}
+         [{<literal>eq</literal>|<literal>neq</literal>|<literal>gt</literal>|<literal>lt</literal>}
+         <replaceable>port</replaceable>|<literal>range</literal>
+         <replaceable>from</replaceable>
+         <replaceable>to</replaceable>]
+         [{<literal>established</literal>|{<literal>match-any</literal>|<literal>match-all</literal>}
+         {<literal>+</literal>|<literal>-</literal>}{<literal>fin</literal>|<literal>syn</literal>|<literal>rst</literal>|<literal>psh</literal>|<literal>ack</literal>|<literal>urg</literal>}
+         ...|<literal>fragments</literal>]
+       </para>
+      </sect3>
+    </sect2>
+
+    <sect2 id="config-users">
+      <title><filename>users</filename></title>
+      <para>
+       Usernames and passwords for the command-line interface are
+       stored in this file.  The format is
+<synopsis>
+<replaceable>username</replaceable>:<replaceable>password</replaceable>
+</synopsis>
+       where <replaceable>password</replaceable> may either by plain
+       text, an MD5 digest (prefixed by
+       <literal>$1</literal><replaceable>salt</replaceable><literal>$</literal>)
+       or a DES password, distinguished from plain text by the prefix
+       <literal>{crypt}</literal>.
+      </para>
+
+      <para>
+       The username <literal>enable</literal> has a special meaning
+       and is used to set the enable password.
+      </para>
+
+      <important>
+       <para>
+         If this file doesn't exist, then anyone who can get to port
+         23 will be allowed access without a username or password.
+       </para>
+      </important>
+    </sect2>
+
+    <sect2 id="config-ip-pool">
+      <title><filename>ip_pool</filename></title>
+      <para>
+       This file is used to configure the IP address pool which user
+       addresses are assigned from.  This file should contain either
+       an IP address or a CIDR network per line.  e.g.:
+
+<programlisting>
+192.168.1.1
+192.168.1.2
+192.168.1.3
+192.168.4.0/24
+172.16.0.0/16
+10.0.0.0/8
+</programlisting>
+      </para>
+
+      <para>
+       Keep in mind that <command>l2tpns</command> can only handle
+       65535 connections per process, so don't put more than 65535 IP
+       addresses in the configuration file.  They will be
+       wasted.
+      </para>
+    </sect2>
+
+    <sect2 id="config-build-garden" xreflabel="build-garden">
+      <title><filename>build-garden</filename></title>
+      <para>
+       The garden plugin on startup creates a NAT table called
+       "garden" then sources the <filename>build-garden</filename>
+       script to populate that table.  All packets from gardened
+       users will be sent through this table.  Example:
+
+<programlisting>
+iptables -t nat -A garden -p tcp -m tcp --dport 25 -j DNAT --to 192.168.1.1
+iptables -t nat -A garden -p udp -m udp --dport 53 -j DNAT --to 192.168.1.1
+iptables -t nat -A garden -p tcp -m tcp --dport 53 -j DNAT --to 192.168.1.1
+iptables -t nat -A garden -p tcp -m tcp --dport 80 -j DNAT --to 192.168.1.1
+iptables -t nat -A garden -p tcp -m tcp --dport 110 -j DNAT --to 192.168.1.1
+iptables -t nat -A garden -p tcp -m tcp --dport 443 -j DNAT --to 192.168.1.1
+iptables -t nat -A garden -p icmp -m icmp --icmp-type echo-request -j DNAT --to 192.168.1.1
+iptables -t nat -A garden -p icmp -j ACCEPT
+iptables -t nat -A garden -j DROP
+</programlisting>
+      </para>
+    </sect2>
+  </sect1>
+
+  <sect1 id="operation">
+    <title>Operation</title>
+    <para>
+      A running l2tpns process can be controlled in a number of ways.
+      The primary method of control is by the Command-Line Interface
+      (CLI).
+    </para>
+
+    <para>
+      You can also remotely send commands to modules via the
+      <command>nsctl</command> client provided.
+    </para>
+
+    <para>
+      There are also a number of signals that l2tpns understands and
+      takes action when it receives them.
+    </para>
+
+    <sect2 id="operation-cli">
+      <title>Command-Line Interface</title>
+      <para>
+       You can access the command line interface by telneting to port
+       23.  There is no IP address restriction, so it's a good idea
+       to firewall this port off from anyone who doesn't need access
+       to it.  See <xref linkend="config-users"/> for information on
+       restricting access based on a username and password.
+      </para>
+
+      <para>
+       The CLI gives you real-time control over almost everything in
+       the process.  The interface is designed to look like a Cisco
+       device, and supports things like command history, line editing
+       and context sensitive help.  This is provided by linking with
+       the <ulink url="http://sourceforge.net/projects/libcli">
+       libcli</ulink> library.  Some general documentation of the
+       interface is <ulink
+       url="http://sourceforge.net/docman/display_doc.php?docid=20501&amp;group_id=79019">
+       here</ulink>.
+      </para>
+
+      <para>
+       After you have connected to the telnet port (and perhaps
+       logged in), you will be presented with a
+       <prompt><replaceable>hostname</replaceable>&gt;</prompt>
+       prompt.
+      </para>
+
+      <para>
+       Enter <userinput>help</userinput> to get a list of possible
+       commands, or press <userinput>?</userinput> for
+       context-specific help.
+      </para>
+
+      <para>
+       A brief overview of the more important commands
+       follows:
+
+       <variablelist>
+         <varlistentry id="operation-cli-show-session"
+             xreflabel="show session">
+           <term>
+             <userinput>show session [<replaceable>ID</replaceable>]
+             </userinput>
+           </term>
+
+           <listitem>
+             <para>
+               Detailed information for a specific session is
+               presented if you specify a session
+               <replaceable>ID</replaceable> argument.
+             </para>
+
+             <para>
+               If no <replaceable>ID</replaceable> is given, a
+               summary of all connected sessions is produced.  Note
+               that this summary list can be around 185 columns wide,
+               so you should probably use a wide
+               terminal.
+             </para>
+
+             <para>
+               The columns listed in the summary are:
+
+               <informaltable>
+                 <tgroup cols="3">
+                   <colspec colname="col"/>
+                   <colspec colname="desc"/>
+                   <colspec colname="extra"/>
+                   <tbody>
+                     <row>
+                       <entry><literal>SID</literal></entry>
+                       <entry namest="desc" nameend="extra">Session ID</entry>
+                     </row>
+                     <row>
+                       <entry><literal>TID</literal></entry>
+                       <entry>Tunnel ID</entry>
+                       <entry>
+                         See also the <xref
+                         linkend="operation-cli-show-tunnel"/> CLI
+                         command.
+                       </entry>
+                     </row>
+                     <row>
+                       <entry><literal>Username</literal></entry>
+                       <entry>
+                         The username given in the PPP authentication.
+                       </entry>
+                       <entry>
+                         If this is *, then LCP authentication has
+                         not completed.
+                       </entry>
+                     </row>
+                     <row>
+                       <entry><literal>IP</literal></entry>
+                       <entry>The IP address given to the session.</entry>
+                       <entry>
+                         If this is 0.0.0.0, IPCP negotiation has not
+                         completed
+                       </entry>
+                     </row>
+                     <row>
+                       <entry><literal>I</literal></entry>
+                       <entry>Intercept</entry>
+                       <entry>
+                         Y or N: indicates whether the session is
+                         being snooped.  See also the
+                         <xref linkend="operation-cli-snoop"/>
+                         CLI command.
+                       </entry>
+                     </row>
+                     <row>
+                       <entry><literal>T</literal></entry>
+                       <entry>Throttled</entry>
+                       <entry>
+                         Y or N: indicates whether the session is
+                         currently throttled.  See also the
+                         <xref linkend="operation-cli-throttle"/>
+                         CLI command.
+                       </entry>
+                     </row>
+                     <row>
+                       <entry><literal>G</literal></entry>
+                       <entry>Walled Garden</entry>
+                       <entry>
+                         Y or N:  indicates whether the user is
+                         trapped in the walled garden.  This field is
+                         present even if the garden module is not
+                         loaded.
+                       </entry>
+                     </row>
+                     <row>
+                       <entry><literal>6</literal></entry>
+                       <entry>IPv6</entry>
+                       <entry>
+                         Y or N:  indicates whether the session has
+                         IPv6 active (IPV6CP open)
+                       </entry>
+                     </row>
+                     <row>
+                       <entry><literal>opened</literal></entry>
+                       <entry namest="desc" nameend="extra">
+                         The number of seconds since the
+                         session started
+                       </entry>
+                     </row>
+                     <row>
+                       <entry><literal>downloaded</literal></entry>
+                       <entry namest="desc" nameend="extra">
+                         Number of bytes downloaded by the user
+                       </entry>
+                     </row>
+                     <row>
+                       <entry><literal>uploaded</literal></entry>
+                       <entry namest="desc" nameend="extra">
+                         Number of bytes uploaded by the user
+                       </entry>
+                     </row>
+                     <row>
+                       <entry><literal>idle</literal></entry>
+                       <entry namest="desc" nameend="extra">
+                         The number of seconds since traffic was
+                         detected on the session
+                       </entry>
+                     </row>
+                     <row>
+                       <entry><literal>LAC</literal></entry>
+                       <entry namest="desc" nameend="extra">
+                         The IP address of the LAC the session is
+                         connected to.
+                       </entry>
+                     </row>
+                     <row>
+                       <entry><literal>CLI</literal></entry>
+                       <entry namest="desc" nameend="extra">
+                         The Calling-Line-Identification field
+                         provided during the session setup.  This
+                         field is generated by the LAC.
+                       </entry>
+                     </row>
+                   </tbody>
+                 </tgroup>
+               </informaltable>
+             </para>
+           </listitem>
+         </varlistentry>
+
+         <varlistentry id="operation-cli-show-user" xreflabel="show user">
+           <term>
+             <userinput>show users</userinput>
+           </term>
+           <term>
+             <userinput>show user <replaceable>username</replaceable>
+             </userinput>
+           </term>
+
+           <listitem>
+             <para>
+               With no arguments, display a list of currently
+               connected users.  If an argument is given, the session
+               details for the given
+               <replaceable>username</replaceable> are displayed.
+             </para>
+           </listitem>
+         </varlistentry>
+
+         <varlistentry id="operation-cli-show-tunnel" xreflabel="show tunnel">
+           <term>
+             <userinput>show tunnel [<replaceable>ID</replaceable>]</userinput>
+           </term>
+
+           <listitem>
+             <para>
+               Produce a summary list of all open tunnels, or detail
+               on a specific tunnel <replaceable>ID</replaceable>.
+             </para>
+
+             <para>
+               The columns listed in the summary are:
+
+               <informaltable>
+                 <tgroup cols="2">
+                   <tbody>
+                     <row>
+                       <entry>TID</entry>
+                       <entry>Tunnel ID</entry>
+                     </row>
+                     <row>
+                       <entry>Hostname</entry>
+                       <entry>
+                         The hostname for the tunnel as provided by
+                         the LAC.  This has no relation to DNS, it is
+                         just a text field.
+                       </entry>
+                     </row>
+                     <row>
+                       <entry>IP</entry>
+                       <entry>The IP address of the LAC</entry>
+                     </row>
+                     <row>
+                       <entry>State</entry>
+                       <entry>
+                         Tunnel state: Free, Open, Dieing, Opening
+                       </entry>
+                     </row>
+                     <row>
+                       <entry>Sessions</entry>
+                       <entry>The number of open sessions on the tunnel</entry>
+                     </row>
+                   </tbody>
+                 </tgroup>
+               </informaltable>
+             </para>
+           </listitem>
+         </varlistentry>
+
+         <varlistentry id="operation-cli-show-pool" xreflabel="show pool">
+           <term><userinput>show pool</userinput></term>
+           <listitem>
+             <para>
+               Displays the current IP address pool allocation.  This
+               will only display addresses that are in use, or are
+               reserved for re-allocation to a disconnected user.
+             </para>
+
+             <para>
+               If an address is not currently in use, but has been
+               used, then in the User column the username will be
+               shown in square brackets, followed by the time since
+               the address was used:
+
+<screen>
+IP Address      Used  Session User
+192.168.100.6     N           [joe.user] 1548s
+</screen>
+             </para>
+           </listitem>
+         </varlistentry>
+
+         <varlistentry id="operation-cli-show-radius" xreflabel="show radius">
+           <term><userinput>show radius</userinput></term>
+           <listitem>
+             <para>
+               Show a summary of the in-use RADIUS sessions.  This
+               list should not be very long, as RADIUS sessions
+               should be cleaned up as soon as they are used.  The
+               columns listed are:
+
+               <informaltable>
+                 <tgroup cols="2">
+                   <tbody>
+                     <row>
+                       <entry>Radius</entry>
+                       <entry>
+                         The ID of the RADIUS request.  This is sent
+                         in the packet to the RADIUS server for
+                         identification
+                       </entry>
+                     </row>
+                     <row>
+                       <entry>State</entry>
+                       <entry>
+                         The state of the request:  WAIT, CHAP, AUTH,
+                         IPCP, START, STOP or NULL
+                       </entry>
+                     </row>
+                     <row>
+                       <entry>Session</entry>
+                       <entry>
+                         The session ID that this RADIUS request is
+                         associated with
+                       </entry>
+                     </row>
+                     <row>
+                       <entry>Retry</entry>
+                       <entry>
+                         If a response does not appear to the
+                         request, it will retry at this time.  This
+                         is a Unix timestamp
+                       </entry>
+                     </row>
+                     <row>
+                       <entry>Try</entry>
+                       <entry>
+                         Retry count.  The RADIUS request is
+                         discarded after 3 retries
+                       </entry>
+                     </row>
+                   </tbody>
+                 </tgroup>
+               </informaltable>
+             </para>
+           </listitem>
+         </varlistentry>
+
+         <varlistentry id="operation-cli-show-run" xreflabel="show run">
+           <term><userinput>show running-config</userinput></term>
+           <listitem>
+             <para>
+               This will list the current running configuration.
+               This is in a format that can either be pasted into the
+               configuration file, or run directly at the command
+               line.
+             </para>
+           </listitem>
+         </varlistentry>
+
+         <varlistentry id="operation-cli-show-counters"
+             xreflabel="show counters">
+           <term><userinput>show counters</userinput></term>
+           <listitem>
+             <para>
+               Internally, counters are kept of key values, such as
+               bytes and packets transferred, as well as function
+               call counters.  This function displays all these
+               counters, and is probably only useful for debugging.
+             </para>
+
+             <para>
+               You can reset these counters by running
+               <userinput>clear counters</userinput>.
+             </para>
+           </listitem>
+         </varlistentry>
+
+         <varlistentry id="operation-cli-show-cluster"
+             xreflabel="show cluster">
+           <term><userinput>show cluster</userinput></term>
+           <listitem>
+             <para>
+               Show cluster status.  Shows the cluster state for this
+               server (Master/Slave), information about known peers
+               and (for slaves) the master IP address, last packet
+               seen and up-to-date status.  See
+               <xref linkend="clustering"/> for more information.
+             </para>
+           </listitem>
+         </varlistentry>
+
+         <varlistentry id="operation-cli-write-mem" xreflabel="write memory">
+           <term><userinput>write memory</userinput></term>
+           <listitem>
+             <para>
+               This will write the current running configuration to
+               the config file <filename>startup-config</filename>,
+               which will be run on a restart.
+             </para>
+           </listitem>
+         </varlistentry>
+
+         <varlistentry id="operation-cli-snoop" xreflabel="snoop">
+           <term>
+             <userinput>snoop <replaceable>user</replaceable>
+               <replaceable>IP</replaceable>
+               <replaceable>port</replaceable></userinput>
+           </term>
+           <listitem>
+             <para>
+               You must specify a username, IP address and port.  All
+               packets for the current session for that username will
+               be forwarded to the given host/port.  Specify
+               <userinput>no snoop
+               <replaceable>username</replaceable></userinput> to
+               disable interception for the session.
+             </para>
+
+             <para>
+               If you want interception to be permanent, you will
+               have to modify the RADIUS response for the user.  See
+               <xref linkend="interception"/>.
+             </para>
+           </listitem>
+         </varlistentry>
+
+         <varlistentry id="operation-cli-throttle" xreflabel="throttle">
+           <term>
+             <userinput>throttle <replaceable>user</replaceable>
+               [in|out] <replaceable>rate</replaceable></userinput>
+           </term>
+           <listitem>
+             <para>
+               You must specify a username, which will be throttled
+               for the current session to
+               <replaceable>rate</replaceable> Kbps.  Prefix
+               <replaceable>rate</replaceable> with
+               <userinput>in</userinput> or
+               <userinput>out</userinput> to set different upstream
+               and downstream rates.
+             </para>
+
+             <para>
+               Specify <userinput>no throttle
+               <replaceable>username</replaceable></userinput> to
+               disable throttling for the current session.
+             </para>
+
+             <para>
+               If you want throttling to be permanent, you will have
+               to modify the RADIUS response for the user.  See <xref
+               linkend="throttling"/>.
+             </para>
+           </listitem>
+         </varlistentry>
+
+         <varlistentry id="operation-cli-drop-session"
+             xreflabel="drop session">
+           <term>
+             <userinput>drop <replaceable>session</replaceable></userinput>
+           </term>
+           <listitem>
+             <para>
+               This will cleanly disconnect the session specified by
+               <replaceable>session</replaceable> ID.
+             </para>
+           </listitem>
+         </varlistentry>
+
+         <varlistentry id="operation-cli-drop-tunnel" xreflabel="drop tunnel">
+           <term>
+             <userinput>drop <replaceable>tunnel</replaceable></userinput>
+           </term>
+           <listitem>
+             <para>
+               This will cleanly disconnect the tunnel specified by
+               <replaceable>tunnel</replaceable> ID, as well as all
+               sessions on that tunnel.
+             </para>
+           </listitem>
+         </varlistentry>
+
+         <varlistentry id="operation-cli-uptime" xreflabel="uptime">
+           <term><userinput>uptime</userinput></term>
+           <listitem>
+             <para>
+               This will show how long the <command>l2tpns</command>
+               process has been running, and the current bandwidth
+               utilization:
+
+<screen>
+17:10:35 up 8 days, 2212 users, load average: 0.21, 0.17, 0.16
+Bandwidth: UDP-ETH:6/6  ETH-UDP:13/13  TOTAL:37.6   IN:3033 OUT:2569
+</screen>
+
+               The bandwidth line contains 4 sets of values:
+
+               <informaltable>
+                 <tgroup cols="2">
+                   <tbody>
+                     <row>
+                       <entry>UDP-ETH</entry>
+                       <entry>
+                         The current bandwidth going from the LAC to
+                         the ethernet (user uploads), in mbits/sec.
+                       </entry>
+                     </row>
+                     <row>
+                       <entry>ETH-UDP</entry>
+                       <entry>
+                         The current bandwidth going from ethernet to
+                         the LAC (user downloads).
+                       </entry>
+                     </row>
+                     <row>
+                       <entry>TOTAL</entry>
+                       <entry>The total aggregate bandwidth in mbits/s.</entry>
+                     </row>
+                     <row>
+                       <entry>IN and OUT</entry>
+                       <entry>
+                         Packets/per-second going between UDP-ETH and
+                         ETH-UDP.
+                       </entry>
+                     </row>
+                   </tbody>
+                 </tgroup>
+               </informaltable>
+
+               These counters are updated every second.
+             </para>
+           </listitem>
+         </varlistentry>
+
+         <varlistentry id="operation-cli-configure" xreflabel="configure">
+           <term><userinput>configure terminal</userinput></term>
+           <listitem>
+             <para>
+               Enter configuration mode.  Use
+               <userinput>exit</userinput> or
+               <userinput>^Z</userinput> to exit this mode.
+             </para>
+
+             <para>
+               The following commands are valid in this mode:
+
+               <variablelist>
+                 <varlistentry id="operation-cli-conf-load">
+                   <term>
+                     <userinput>load plugin
+                       <replaceable>name</replaceable></userinput>
+                   </term>
+                   <listitem>
+                     <para>
+                       Load a plugin.  You must specify the plugin
+                       name, and it will search in
+                       <filename>/usr/lib/l2tpns</filename> for
+                       <filename><replaceable>name</replaceable>.so</filename>.
+                       You can unload a loaded plugin with
+                       <userinput>remove plugin
+                       <replaceable>name</replaceable></userinput>.
+                     </para>
+                   </listitem>
+                 </varlistentry>
+
+                 <varlistentry id="operation-cli-conf-set">
+                   <term><userinput>set</userinput> ...</term>
+                   <listitem>
+                     <para>
+                       Set a configuration variable.  You must specify
+                       the variable name, and the value.  If the value
+                       contains any spaces, you should quote the value
+                       with double (") or single (') quotes.
+                     </para>
+
+                     <para>
+                       You can set any configuration value in this
+                       way, although some may require a restart to
+                       take effect.  See <xref
+                       linkend="config-startup"/>.
+                     </para>
+                   </listitem>
+                 </varlistentry>
+
+                 <varlistentry id="operation-cli-conf-router">
+                   <term><userinput>router bgp</userinput> ...</term>
+                   <listitem>
+                     <para>
+                       Configure BGP.  See <xref
+                       linkend="config-startup-bgp"/>.
+                     </para>
+                   </listitem>
+                 </varlistentry>
+
+                 <varlistentry id="operation-cli-conf-acl">
+                   <term><userinput>ip access-list</userinput> ...</term>
+                   <listitem>
+                     <para>
+                       Configure a named access list.  See <xref
+                       linkend="config-startup-acl"/>.
+                     </para>
+                   </listitem>
+                 </varlistentry>
+               </variablelist>
+             </para>
+           </listitem>
+         </varlistentry>
+       </variablelist>
+      </para>
+    </sect2>
+
+    <sect2 id="operation-nsctl">
+      <title>nsctl</title>
+      <para>
+       <command>nsctl</command> sends messages to a running
+       <command>l2tpns</command> instance to be control plugins.
+      </para>
+
+      <para>
+       Arguments are <userinput>command</userinput> and optional
+       <replaceable>args</replaceable>.  See
+       <literal>nsctl(8)</literal>.
+      </para>
+
+      <para>
+       Built-in command are <userinput>load_plugin</userinput>,
+       <userinput>unload_plugin</userinput> and
+       <userinput>help</userinput>.  Any other commands are passed to
+       plugins for processing by the
+       <literal>plugin_control</literal> function.
+      </para>
+    </sect2>
+
+    <sect2 id="operation-signals">
+      <title>Signals</title>
+      <para>
+       While the process is running, you can send it a few different
+       signals, using the <command>kill</command> command.
+
+<screen>
+killall -HUP l2tpns
+</screen>
+
+       The signals understood are:
+
+       <variablelist>
+         <varlistentry>
+           <term>SIGHUP</term>
+           <listitem>
+             <para>Reload the config from disk and re-open log file.</para>
+           </listitem>
+         </varlistentry>
+
+         <varlistentry>
+           <term>SIGTERM</term>
+           <term>SIGINT</term>
+           <listitem>
+             <para>
+               Stop process.  Tunnels and sessions are not
+               terminated.  This signal should be used to stop
+               <command>l2tpns</command> on a cluster node where
+               there are other machines to continue handling traffic.
+               See <xref linkend="clustering"/>
+             </para>
+           </listitem>
+         </varlistentry>
+
+         <varlistentry>
+           <term>SIGQUIT</term>
+           <listitem>
+             <para>
+               Shut down tunnels and sessions, exit process when
+               complete.
+             </para>
+           </listitem>
+         </varlistentry>
+       </variablelist>
+      </para>
+    </sect2>
+  </sect1>
+
+  <sect1 id="throttling">
+    <title>Throttling</title>
+    <para>
+      <command>l2tpns</command> contains support for slowing down user
+      sessions to whatever speed you desire.  The global setting
+      <literal>throttle_speed</literal> defines the default throttle
+      rate.
+    </para>
+
+    <para>
+      To throttle a sesion permanently, add a
+      <literal>Cisco-AVPair</literal> RADIUS attribute.  The
+      <filename>autothrotle</filename> module interprets the following
+      attributes:
+
+      <informaltable>
+       <tgroup cols="2">
+         <tbody>
+           <row>
+             <entry><literal>throttle=yes</literal></entry>
+             <entry>
+               Throttle upstream/downstream traffic to the configured
+               <literal>throttle_speed</literal>.
+             </entry>
+           </row>
+
+           <row>
+             <entry>
+               <literal>throttle=<replaceable>rate</replaceable></literal>
+             </entry>
+             <entry>
+               Throttle upstream/downstream traffic to the specified
+               <replaceable>rate</replaceable> Kbps.
+             </entry>
+           </row>
+
+           <row>
+             <entry>
+               <literal>lcp:interface-config#1=service-policy input
+                 <replaceable>rate</replaceable></literal>
+             </entry>
+
+             <entry morerows="1">
+               Alternate (Cisco) format:  throttle
+               upstream/downstream to specified
+               <replaceable>rate</replaceable> Kbps.
+             </entry>
+           </row>
+
+           <row>
+             <entry>
+               <literal>lcp:interface-config#2=service-policy output
+                 <replaceable>rate</replaceable></literal>
+             </entry>
+           </row>
+         </tbody>
+       </tgroup>
+      </informaltable>
+    </para>
+
+    <para>
+      You can also enable and disable throttling an active session
+      using the <xref linkend="operation-cli-throttle"/> CLI command.
+    </para>
+  </sect1>
+
+  <sect1 id="interception">
+    <title>Interception</title>
+    <para>
+      You may have to deal with legal requirements to be able to
+      intercept a user's traffic at any time.
+      <command>l2tpns</command> allows you to begin and end
+      interception on the fly, as well as at authentication time.
+    </para>
+
+    <para>
+      When a user is being intercepted, a copy of every packet they
+      send and receive will be sent wrapped in a UDP packet to a
+      specified host.
+    </para>
+
+    <para>
+      The UDP packet contains just the raw IP frame, with no extra
+      headers.  The script <filename>scripts/l2tpns-capture</filename>
+      may be used as the end-point for such intercepts, writing the
+      data in PCAP format (suitable for inspection with
+      <command>tcpdump</command>).
+    </para>
+
+    <para>
+      To enable or disable interception of a connected user, use the
+      <xref linkend="operation-cli-snoop"/> and <userinput>no
+      snoop</userinput> CLI commands.  These will enable interception
+      immediately.
+    </para>
+
+    <para>
+      If you wish the user to be intercepted whenever they reconnect,
+      you will need to modify the RADIUS response to include the
+      Vendor-Specific value
+      <literal>Cisco-AVPair="intercept=<replaceable>ip</replaceable>:<replaceable>port</replaceable>"</literal>.
+      For this feature to be enabled, you need to have the
+      <filename>autosnoop</filename> module loaded.
+    </para>
+  </sect1>
+
+  <sect1 id="plugins">
+    <title>Plugins</title>
+    <para>
+      So as to make <command>l2tpns</command> as flexible as possible,
+      a plugin API is include which you can use to hook into certain
+      events.
+    </para>
+
+    <para>
+      There are a some standard modules included which may be used as
+      examples:  <filename>autosnoop</filename>,
+      <filename>autothrottle</filename>, <filename>garden</filename>,
+      <filename>sessionctl</filename>,
+      <filename>setrxspeed</filename>, <filename>snoopctl</filename>,
+      <filename>stripdomain</filename> and
+      <filename>throttlectl</filename>.
+    </para>
+
+    <para>
+      When an event occurs that has a hook, <command>l2tpns</command>
+      looks for a predefined function name in every loaded module, and
+      runs them in the order the modules were loaded.
+    </para>
+
+    <para>
+      The function should return <code>PLUGIN_RET_OK</code> if it is
+      all OK.  If it returns <code>PLUGIN_RET_STOP</code>, then it is
+      assumed to have worked, but that no further modules should be
+      run for this event.
+    </para>
+
+    <para>
+      A return of <code>PLUGIN_RET_ERROR</code> means that this module
+      failed, and no further processing should be done for this event.
+      <note><para>Use this with care.</para></note>
+    </para>
+
+    <para>
+      Most event functions take a specific structure named
+      <code>param_<replaceable>event</replaceable></code>, which
+      varies in content with each event.  The function name for each
+      event will be
+      <code>plugin_<replaceable>event</replaceable></code>, so for the
+      event <replaceable>timer</replaceable>, the function declaration
+      should look like:
+
+<programlisting>
+int plugin_timer(struct param_timer *data);
+</programlisting>
+
+      A list of the available events follows, with a list of all the
+      fields in the supplied structure:
+
+      <informaltable>
+       <tgroup cols="4">
+         <colspec colname="event"/>
+         <colspec colname="event_desc"/>
+         <colspec colname="member"/>
+         <colspec colname="member_desc"/>
+         <spanspec spanname="args" namest="member" nameend="member_desc"/>
+         <thead>
+           <row>
+             <entry>Event</entry>
+             <entry>Description</entry>
+             <entry spanname="args">Arguments</entry>
+           </row>
+         </thead>
+
+         <tbody>
+           <row>
+             <entry morerows="1"><code>plugin_init</code></entry>
+             <entry morerows="1">
+               <para>
+                 Called when the plugin is loaded.  A pointer to a
+                 struct containing function pointers is passed as the
+                 only argument, allowing the plugin to call back into
+                 the main code.
+               </para>
+               <para>
+                 Prior to loading the plugin, <command>l2tpns</command>
+                 checks the API version the plugin was compiled
+                 against.  All plugins should contain:
+<programlisting>
+int plugin_api_version = PLUGIN_API_VERSION;
+</programlisting>
+               </para>
+             </entry>
+             <entry spanname="args"><code>struct pluginfuncs *</code></entry>
+           </row>
+           <row>
+             <entry spanname="args">
+               See <code>pluginfuncs</code> structure in
+               <code>plugin.h</code> for available functions.
+             </entry>
+           </row>
+
+           <row>
+             <entry morerows="1"><code>plugin_done</code></entry>
+             <entry morerows="1">
+               Called when the plugin is unloaded or
+               <command>l2tpns</command> is shutdown.
+             </entry>
+             <entry spanname="args"><code>void</code></entry>
+           </row>
+           <row>
+             <entry spanname="args">No arguments.</entry>
+           </row>
+
+           <row>
+             <entry morerows="6"><code>plugin_pre_auth</code></entry>
+             <entry morerows="6">
+               Called after a RADIUS response has been received, but
+               before it has been processed by the code.  This will
+               allow you to modify the response in some way.
+             </entry>
+             <entry spanname="args">
+               <code>struct plugin param_pre_auth *</code>
+             </entry>
+           </row>
+           <row>
+             <entry><code>tunnelt *t</code></entry>
+             <entry>Tunnel.</entry>
+           </row>
+           <row>
+             <entry><code>sessiont *s</code></entry>
+             <entry>Session.</entry>
+           </row>
+           <row>
+             <entry><code>char *username</code></entry>
+             <entry>User name.</entry>
+           </row>
+           <row>
+             <entry><code>char *password</code></entry>
+             <entry>Password.</entry>
+           </row>
+           <row>
+             <entry><code>int protocol</code></entry>
+             <entry>
+               Authentication protocol: <literal>0xC023</literal> for PAP,
+               <literal>0xC223</literal> for CHAP.
+             </entry>
+           </row>
+           <row>
+             <entry><code>int continue_auth</code></entry>
+             <entry>Set to 0 to stop processing authentication modules.</entry>
+           </row>
+
+           <row>
+             <entry morerows="5"><code>plugin_post_auth</code></entry>
+             <entry morerows="5">
+               Called after a RADIUS response has been received, and
+               the basic checks have been performed.  This is what
+               the <filename>garden</filename> module uses to force
+               authentication to be accepted.
+             </entry>
+             <entry spanname="args">
+               <code>struct plugin param_post_auth *</code>
+             </entry>
+           </row>
+           <row>
+             <entry><code>tunnelt *t</code></entry>
+             <entry>Tunnel.</entry>
+           </row>
+           <row>
+             <entry><code>sessiont *s</code></entry>
+             <entry>Session.</entry>
+           </row>
+           <row>
+             <entry><code>char *username</code></entry>
+             <entry>User name.</entry>
+           </row>
+           <row>
+             <entry><code>short auth_allowed</code></entry>
+             <entry>
+               Initially true or false depending on whether
+               authentication has been allowed so far.  You can
+               set this to 1 or 0 to force authentication to be
+               accepted or rejected.
+             </entry>
+           </row>
+           <row>
+             <entry><code>int protocol</code></entry>
+             <entry>
+               Authentication protocol: <literal>0xC023</literal> for PAP,
+               <literal>0xC223</literal> for CHAP.
+             </entry>
+           </row>
+
+           <row>
+             <entry morerows="1"><code>plugin_timer</code></entry>
+             <entry morerows="1">
+               Run once per second.
+             </entry>
+             <entry spanname="args">
+               <code>struct plugin param_timer *</code>
+             </entry>
+           </row>
+           <row>
+             <entry><code>time_t time_now</code></entry>
+             <entry>The current unix timestamp.</entry>
+           </row>
+
+           <row>
+             <entry morerows="2"><code>plugin_new_session</code></entry>
+             <entry morerows="2">
+               Called after a session is fully set up.  The session
+               is now ready to handle traffic.
+             </entry>
+             <entry spanname="args">
+               <code>struct plugin param_new_session *</code>
+             </entry>
+           </row>
+           <row>
+             <entry><code>tunnelt *t</code></entry>
+             <entry>Tunnel.</entry>
+           </row>
+           <row>
+             <entry><code>sessiont *s</code></entry>
+             <entry>Session.</entry>
+           </row>
+
+           <row>
+             <entry morerows="2"><code>plugin_kill_session</code></entry>
+             <entry morerows="2">
+               Called when a session is about to be shut down.  This
+               may be called multiple times for the same session.
+             </entry>
+             <entry spanname="args">
+               <code>struct plugin param_kill_session *</code>
+             </entry>
+           </row>
+           <row>
+             <entry><code>tunnelt *t</code></entry>
+             <entry>Tunnel.</entry>
+           </row>
+           <row>
+             <entry><code>sessiont *s</code></entry>
+             <entry>Session.</entry>
+           </row>
+
+           <row>
+             <entry morerows="5"><code>plugin_control</code></entry>
+             <entry morerows="5">
+               <para>
+                 Called in whenever a <command>nsctl</command> packet
+                 is received.  This should handle the packet and form a
+                 response if required.
+               </para>
+               <para>
+                 Plugin-specific help strings may be included in the
+                 output of <userinput>nsctl help</userinput> by
+                 defining a <code>NULL</code> terminated list of
+                 strings as follows:
+<programlisting>
+char *plugin_control_help[] = { <replaceable>...</replaceable>, NULL };
+</programlisting>
+               </para>
+             </entry>
+             <entry spanname="args">
+               <code>struct plugin param_control *</code>
+             </entry>
+           </row>
+           <row>
+             <entry><code>int iam_master</code></entry>
+             <entry>If true, this node is the cluster master.</entry>
+           </row>
+           <row>
+             <entry><code>int argc</code></entry>
+             <entry morerows="1"><command>nsctl</command> arguments.</entry>
+           </row>
+           <row>
+             <entry><code>char **argc</code></entry>
+           </row>
+           <row>
+             <entry><code>int reponse</code></entry>
+             <entry>
+               Response from control message (if handled):  should be
+               either <code>NSCTL_RES_OK</code> or
+               <code>NSCTL_RES_ERR</code>.
+             </entry>
+           </row>
+           <row>
+             <entry><code>char *additional</code></entry>
+             <entry>
+               Additional information, output by
+               <command>nsctl</command> on receiving the response.
+             </entry>
+           </row>
+
+           <row>
+             <entry morerows="4"><code>plugin_radius_response</code></entry>
+             <entry morerows="4">
+               Called whenever a RADIUS response includes a
+               <literal>Cisco-AVPair</literal> value.  The value is
+               split into
+               <replaceable>key</replaceable><literal>=</literal><replaceable>value</replaceable>
+               pairs.  Will be called once for each pair in the
+               response.
+             </entry>
+             <entry spanname="args">
+               <code>struct plugin param_radius_response *</code>
+             </entry>
+           </row>
+           <row>
+             <entry><code>tunnelt *t</code></entry>
+             <entry>Tunnel.</entry>
+           </row>
+           <row>
+             <entry><code>sessiont *s</code></entry>
+             <entry>Session.</entry>
+           </row>
+           <row>
+             <entry><code>char *key</code></entry>
+             <entry morerows="1">Key and value.</entry>
+           </row>
+           <row>
+             <entry><code>char *value</code></entry>
+           </row>
+
+           <row>
+             <entry morerows="2"><code>plugin_radius_reset</code></entry>
+             <entry morerows="2">
+               Called whenever a RADIUS CoA request is received to
+               reset any options to default values before the new
+               values are applied.
+             </entry>
+             <entry spanname="args">
+               <code>struct param_radius_reset *</code>
+             </entry>
+           </row>
+           <row>
+             <entry><code>tunnelt *t</code></entry>
+             <entry>Tunnel.</entry>
+           </row>
+           <row>
+             <entry><code>sessiont *s</code></entry>
+             <entry>Session.</entry>
+           </row>
+
+           <row>
+             <entry morerows="3"><code>plugin_radius_account</code></entry>
+             <entry morerows="3">
+               Called when preparing a RADIUS accounting record to
+               allow additional data to be added to the packet.
+             </entry>
+             <entry spanname="args">
+               <code>struct param_radius_account *</code>
+             </entry>
+           </row>
+           <row>
+             <entry><code>tunnelt *t</code></entry>
+             <entry>Tunnel.</entry>
+           </row>
+           <row>
+             <entry><code>sessiont *s</code></entry>
+             <entry>Session.</entry>
+           </row>
+           <row>
+             <entry><code>uint8_t **packet</code></entry>
+             <entry>
+               Pointer to the end of the currently assembled
+               packet buffer.  The value should be incremented by the
+               length of any data added.
+             </entry>
+           </row>
+
+           <row>
+             <entry morerows="1"><code>plugin_become_master</code></entry>
+             <entry morerows="1">
+               Called when a node elects itself cluster master.
+             </entry>
+             <entry spanname="args"><code>void</code></entry>
+           </row>
+           <row>
+             <entry spanname="args">No arguments.</entry>
+           </row>
+
+           <row>
+             <entry morerows="1"><code>plugin_new_session_master</code></entry>
+             <entry morerows="1">
+               Called once for each open session on becoming cluster
+               master.
+             </entry>
+             <entry spanname="args"><code>sessiont *</code></entry>
+           </row>
+           <row>
+             <entry spanname="args">
+               Session.
+             </entry>
+           </row>
+         </tbody>
+       </tgroup>
+      </informaltable>
+    </para>
+  </sect1>
+
+  <sect1 id="walled-garden">
+    <title>Walled Garden</title>
+    <para>
+      A "Walled Garden" is implemented so that you can provide perhaps
+      limited service to sessions that incorrectly authenticate.
+    </para>
+
+    <para>
+      Whenever a session provides incorrect authentication, and the
+      RADIUS server responds with Auth-Reject, the walled garden
+      module (if loaded) will force authentication to succeed, but set
+      the <literal>walled_garden</literal> flag in the session
+      structure, and adds an <command>iptables</command> rule to the
+      <literal>garden_users</literal> chain to cause all packets for
+      the session to traverse the <literal>garden</literal> chain.
+    </para>
+
+    <para>
+      This doesn't <emphasis>just work</emphasis>.  To set this all
+      up, you will to setup the <literal>garden</literal> nat table
+      with the <xref linkend="config-build-garden"/> script with rules
+      to limit user's traffic.
+    </para>
+
+    <para>
+      For example, to force all traffic except DNS to be forwarded to
+      192.168.1.1, add these entries to your
+      <filename>build-garden</filename> script:
+
+<programlisting>
+iptables -t nat -A garden -p tcp --dport ! 53 -j DNAT --to 192.168.1.1
+iptables -t nat -A garden -p udp --dport ! 53 -j DNAT --to 192.168.1.1
+</programlisting>
+    </para>
+
+    <para>
+      <command>l2tpns</command> will add entries to the
+      <literal>garden_users</literal> chain as appropriate.
+    </para>
+
+    <para>
+      You can check the amount of traffic being captured using the
+      following command:
+
+<screen>
+iptables -t nat -L garden -nvx
+</screen>
+    </para>
+  </sect1>
+
+  <sect1 id="filtering">
+    <title>Filtering</title>
+    <para>
+      Sessions may be filtered by specifying
+      <literal>Filter-Id</literal> attributes in the RADIUS reply.
+      <replaceable>filter</replaceable>.<literal>in</literal>
+      specifies that the named access-list
+      <replaceable>filter</replaceable> should be applied to traffic
+      from the customer,
+      <replaceable>filter</replaceable>.<literal>out</literal>
+      specifies a list for traffic to the customer.
+    </para>
+  </sect1>
+
+  <sect1 id="clustering">
+    <title>Clustering</title>
+    <para>
+      An <command>l2tpns</command> cluster consists of one* or more
+      servers configured with the same configuration, notably the
+      multicast <literal>cluster_address</literal>.
+    </para>
+
+    <para>*A stand-alone server is simply a degraded cluster.</para>
+
+    <para>
+      Initially servers come up as cluster slaves, and periodically
+      (every <literal>cluster_hb_interval</literal>/10 seconds) send
+      out ping packets containing the start time of the process to the
+      multicast <literal>cluster_address</literal>.
+    </para>
+
+    <para>
+      A cluster master sends heartbeat rather than ping packets, which
+      contain those session and tunnel changes since the last
+      heartbeat.
+    </para>
+
+    <para>
+      When a slave has not seen a heartbeat within
+      <literal>cluster_hb_timeout</literal>/10 seconds it "elects" a
+      new master by examining the list of peers it has seen pings from
+      and determines which of these and itself is the "best" candidate
+      to be master.  "Best" in this context means the server with the
+      highest uptime (the highest IP address is used as a tie-breaker
+      in the case of equal uptimes).
+    </para>
+
+    <para>
+      After discovering a master, and determining that it is
+      up-to-date (has seen an update for all in-use sessions and
+      tunnels from heartbeat packets) will raise a route (see <xref
+      linkend="routing"/>) for the <literal>bind_address</literal> and
+      for all addresses/networks in <filename>ip_pool</filename>.
+    </para>
+
+    <para>
+      Any packets recieved by the slave which would alter the session
+      state, as well as packets for throttled or gardened sessions are
+      forwarded to the master for handling.  In addition, byte
+      counters for session traffic are periodically forwarded.
+    </para>
+
+    <para>
+      The master, when determining that it has at least one* up-to-date
+      slave will drop all routes (raising them again if all slaves
+      disappear) and subsequently handle only packets forwarded to it
+      by the slaves.
+    </para>
+
+    <para>*Configurable with <literal>cluster_master_min_adv</literal></para>
+  </sect1>
+
+  <sect1 id="routing">
+    <title>Routing</title>
+    <para>
+      If you are running a single instance, you may simply statically
+      route the IP pools to the <literal>bind_address</literal>
+      (<command>l2tpns</command> will send a gratuitous arp).
+    </para>
+
+    <para>
+      For a cluster, configure the members as BGP neighbours on your
+      router and configure multi-path load-balancing.  Cisco uses
+      <userinput>maximum-paths ibgp</userinput> for IBGP.  If this is
+      not supported by your IOS revision, you can use
+      <userinput>maximum-paths</userinput> (which works for EBGP) and
+      set <literal>as_number</literal> to a private value such as
+      64512.
+    </para>
+  </sect1>
+</article>
index c46d3ae..15fffac 100644 (file)
@@ -43,5 +43,5 @@ rm -rf %{buildroot}
 %attr(644,root,root) /usr/share/man/man[58]/*
 
 %changelog
-* Fri Apr 28 2006 Brendan O'Dea <bod@optus.net> 2.2.0-1
+* Wed May 24 2006 Brendan O'Dea <bod@optus.net> 2.2.0-1
 - 2.2.0 release, see /usr/share/doc/l2tpns-2.2.0/Changes