Copyright (C) 2009  Internet Systems Consortium, Inc. ("ISC")

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

$Id: README 220 2009-07-08 22:11:38Z fdupont $


1. INTRODUCTION

This is a stand-alone, user mode application that implements a
dual-stack lite (ds-lite) carrier-grade NAT (CGN) as described in
draft-ietf-softwire-dual-stack-lite-00.txt.  It is expected to work on
operating systems that support the tun(4) device, and has been tested
on Linux and FreeBSD.

The primary purpose of this implementation is to provide a proof of
concept of the specification.  While it is implemented to be
reasonably scalable with regard to the number NAT connections and
the number of IPv4/IPv6 tunnels, it is generally not expected to be
used in a production environment.  Likewise, configuration and
management flexibility are limited.

1.1 System Requirements

- OS: Linux or FreeBSD.  Linux kernel version must be >= 2.6.26, to
  correct a small-packet-drop problem in tunnel46_rcv().

- CPU: Shouldn't matter, but we have only tested it with the Intel
  architecture.  Either 32 or 64 bit CPU should be okay.
  Note that a 32 bit usermode app can run on a 64 bit kernel.

- Memory: No special requirement for the purpose of proof of concept
  with a small number of client hosts. Note the connection tracking of
  netfilter is known to be memory greedy (i.e., >= 16GB system is
  recommended for production).

- Processor speed: No special requirement for the purpose of proof of
  concept with a few number of client hosts. Note the performance
  is bound to the kernel/user context switch latency, so a benchmarking
  program (bench.c, start and stop) is provided; this sends 1M pings to
  192.168.0.4 from 10.0.0.1 through tun0 (*please* change these addresses
  in the code).

2. BUILD

% tar zxvpf cgn-usermode-snapshot-YYYYMMDD.tgz

This creates a a directory named "cgn-usermode-snapshot-YYYYMMDD", which
we refer to as $src_path hereafter.

% cd $src_path
% ./configure
% make

An executable file 'cgn' will be created, the executable binary of the
CGN daemon program.  This is expected to be run on $src_path (there is
no 'make install' step) and when needed under gdb.

2.1 Configuration flags

Here is the list of configuration flags (i.e., CFLAGS):
 - DECAY{1,5,15}: decay values for 1, 5 and 15 mn rates
 - FRAG{6,IN,OUT}_MAXCNT: maximum lengths of reassembly lists
  (0 means disable so the compiler warning is accurate :-)
 - FRAGTN[46]_MAXCNT: maximum lengths per tunnel (on 8 bits)
 - FTPALG: enables the FTP ALG (for testing only)
 - MAXNATCNT: maximum number of NAT entries per tunnel (default is 6000)
 - NOPRIVACY: trace all addresses and ports
 - SIZES: define it to print sizes of principal data structures
 - [TCP|UDP|ICMP]BUCKSZ: per protocol bucket sizes
 - [TCP|UDP]_[MIN|MAX]PORT, ICMP_[MIN|MAX]ID: default port/id ranges
 - USE_TUN_PI: use the tun_pi struct in tun interface/device I/O
  (required on some platforms for IPv6 support)
 - notyet: some unfinished and arguable features

3. CONFIGURATION

3.1 System setup

Linux: Add interface configuration, disable netfilter, enable IPv4 forwarding
(look at confs directory). Note on the testbed interface configuration
needs some help ('service network restart') and netfilter tables to be
flushed ('iptables -F' and 'ip6tables -F') explicitly.

FreeBSD: Add interface configuration, enable IPv4 forwarding
(look at confs/fcgn-rc.conf).

Note: even they don't seem to bother, it is fine to disable ICMP redirects
(Linux net.ipv4.conf.all.send_redirects, FreeBSD net.inet.ip.redirect).

Clients: look at confs directory for configurations used in the testbed.

3.2 Start-up and shut-down scripts

The 'cgn' daemon executes start-up shell script file on invocation.
This must be named 'cgn-start' and located in $src_path.  This could
be even empty, but must exist.

The 'cgn' daemon will eventually execute stop-down shell script file
before it exits (currently this only happens when an error occurs in
the initialization phase).  This must be named 'cgn-stop' and located
in $src_path.

The confs directory provides examples (in fact the scripts used in
our testbed). fcgn-* variants are for a FreeBSD based CGN.

3.3 Configuration File

The 'cgn' daemon requires a configuration file.  It must be named
'cgn-config', and must be located in $src_path.  A sample configuration
file is provided in $src_path/confs/cgn-config (OS independent).

The configuration file consists of a set of one-line configuration
commands.  Commands are not case sensitive.  Any line beginning with '#'
or whitespace is ignored as a comment.

- address interface <IPv4_address> <IPv6_address>
  This specifies two addresses associated with the CGN itself.  This is the
  only command that absolutely must be present in the cgn-config file; the cgn
  daemon will not start without it.

  <IPv4_address> is a global IPv4 address used as the source for ICMP errors
  sent back to the Internet (i.e., the ICMPv4 errors will look like returned
  from an intermediate router that has this address).

  <IPv6_address> is the CGN endpoint address of the Softwire tunnels.  If the
  DHCPv6 ds-lite option is used, this address must match the advertised
  address.

- address <IPv4_address>
  This specifies a global IPv4 address that will be used as the source
  address of NAT'ed packets sent to the Internet.  Multiple global
  addresses can be specified.

- port <IPv4_address> tcp|udp|echo min-max
  This limits the port (or id) range used for the protocol with the
  global IPv4 address in dynamical bindings (i.e., not static or A+P
  bindings which can use the reserved ports outside the range).

- acl6 <IPv6_prefix>/<prefix_length>
  This adds an (accept) entry in the IPv6 ACL. Note for a regular
  IPv6 packet the ACL is checked only when no tunnel was found,
  and the default is "deny all", so at least one acl6 entry in
  the configuration file is required.

- tunnel <IPv6_remote>
  This specifies an IPv4-in-IPv6 tunnel configuration.  <IPv6_remote> is the
  remote (ds-lite client) IPv6 address of the tunnel.

- nat <IPv6_remote> tcp|udp <IPv4_src> <port_src> <IPv4_new> <port_new>
  This defines a static binding/NAT entry for the client behind the tunnel at
  <IPv6_remote>. <*_src> are the source IPv4 address and port at the tunnel
  side of the NAT, <*_new> are the source IPv4 address and port at the
  Internet side of the NAT. <IPv4_new> should be a reserved source NAT
  address.

- prr <IPv6_remote> tcp|udp <IPv4> <port>
  This defines a Port-Range Router/A+P null NAT entry for the client behind
  the tunnel at <IPv6_remote>. <IPv4> and <port> are the source IPv4 address
  and port at the tunnel side of the NAT. They stay unchanged both ways: this
  entry is used to check authorization and perform port routing.

- nonat <IPv6_remote> <IPv4>/<prefix_length>
  This defines a No-NAT tunnel for the client behind the tunnel at
  <IPv6_remote> and the prefix <IPv4>/<prefix_length>. No translation
  is performed for matching packets.

- defmtu <mtu>
  Specifies <mtu> as the default IPv6 MTU of tunnels.  Can be overridden by
  per-tunnel configuration.  If any tunnels are explicitly configured, this
  must be specified before them.

- mtu <IPv6_remote> <mtu>
  This changes the IPv6 MTU of the tunnel of <IPv6_remote> to <mtu>.

- mss on|off
  This enables or disables TCP MSS patching on packets going from and to
  tunnels.  Can be overridden by per-tunnel configuration.  If any tunnels
  are explicitly configured, this must be specified before them.  Default is
  off.

- mss <IPv6_remote> on|off
  This enables or disables TCP MSS patching on packets going from and to the
  tunnel of <IPv6_remote>.  Default is off.

- toobig on|off|strict
  This specifies the policy for packets from the Internet which are too big
  (i.e., they don't fit in one IPv6 encapsulating packet) and are marked
  as "don't fragment". 'On' means a ICMPv4 packet too big error is returned
  to the source, 'off' the packet just go through, and 'strict' the packet
  is dropped with a ICMPv4 error. Default is on (i.e., the packet is
  encapsulated into some IPv6 fragments and a ICMP error is returned for
  path MTU determination).

- toobig <IPv6_remote> on|off|strict
  Per-tunnel configuration of the too big policy.

- eqfrag on|off
  Enables or disables equalizing the length of IPv6 fragments.  Default is
  off.

- autotunnel on|off
  Enables or disables on-the-fly tunnel creation.  Default is on.

- trace <filename>
  Close the current trace file if any and open <filename> as the new
  trace file. State transitions (create/delete of tunnel/nat entries)
  are logged into the trace file if any.

- debug set [<level>]
  Specifies the debug level.  Default is 0.  If set to non 0, verbose log
  messages will be dumped to stderr.  The higher the level is, the noiser
  the logs are.  At present, the meaningful levels are 1 (log tunnel
  creation), 3 (log packet reads and writes), and 10 (function entry
  tracing).  If the level is omitted, it is set to 1.

- show [dropped|stat]
  Aliases of "debug dropped" and "debug stat", display dropped packet and
  general statistics.

- quit
  Orderly quit command.

4. USAGE

Invoke the CGN daemon as follows:

# cd $src_path
# ./cgn

4.1 Interactive commands

The 'cgn' daemon runs in the foreground.  After it starts, it can be
controlled interactively from the console.  (There is no command
prompt, but the command processor is running.)

All of the configuration commands of section 3.3 can be run from the
command line, to add or change configuration.  In addition, the following
commands can be run interactively.

4.1.1 Debug commands

- noop
  Returns 'alive'.

- debug address source|reserved
  This displays the global IPv4 addresses that will be used for dynamic
  ('source') or static ('reserved') NAT bindings (from the 'address' or
  'address reserved' configuration command).

- debug bucket <addr>
  This display information about a single bucket at the <addr> memory
  address.

- debug disable [clear]
  Disable per-tunnel debug counters. Optionally clear them.

- debug dropped
  This display the dropped packet statistics with reasons.

- debug enable <addr>
  Enable per-tunnel debug counters for the tunnel with <addr> remote
  IPv6 address. Note the counters can be incremented only when the
  involved tunnel is known, for instance, only after reassembly.

- debug fragment IPv6|in|out
  This displays the list of IPv4 or IPv6 fragments awaiting reassembly.

- debug fragment <addr>
  This displays information about a single fragment or fragment chain.
  <addr> is the memory address of the fragment structure (from the
  previous 'debug fragment' command).

- debug hash
  This displays some statistics about the various hash tables (fragment,
  nat, and tunnel).

- debug nat
  This displays some information about the nat hash table and entry table.

- debug nat <addr>
  This displays detailed information about a single nat binding.
  <addr> is the memory address of the nat structure (from the previous
  'debug nat' command).

- debug stat
  This displays some general statistics about packets in and out.
  If per-tunnel debug counters are enable, displays them.

- debug tunnel
  This displays some information about the tunnel table.

- debug tunnel <IPv6_remote>
  This displays some information about a single tunnel.

4.1.2 Delete commands

- delete acl6 <IPv6_address>
  This remove the IPv6 ACL entry with the IPv6 address.

- delete nat <IPv6_remote> tcp|udp <IPv4> <port>
  This removes a static or dynamic NAT binding.

- delete nonat <IPv6_remote>
  This removes a no-nat tunnel entry.

- delete prr <IPv6_remote> tcp|udp <IPv4> <port>
  This removes a Port-Range Router/A+P null NAT binding.

- delete tunnel <IPv6_remote>
  This removes a tunnel and all NAT bindings associated with it.

4.1.3 List commands

- list address
  List the NATted source addresses with current port ranges in the
  configuration file format.

- list nat [conf|static|prr|dynamic|all]
  List the NAT entries in the configuration file format. Default is to list
  only the configured ('conf') NAT entries.

- list nonat
  List all the No-NAT tunnel entries in the configuration file format.

- list tunnel
  List the tunnel entries in the configuration file format, including
  specific MTU (if different from the default MTU).
