Skip to content

Commit

Permalink
More documentation tweaks. This inspired the implementation of some #163
Browse files Browse the repository at this point in the history
 features.

The changes are backwards-compatible anyway, so it's alright to release in version 3.4.
  • Loading branch information
ydahhrk committed Sep 10, 2015
1 parent 86b4c64 commit 7416267
Show file tree
Hide file tree
Showing 13 changed files with 355 additions and 222 deletions.
164 changes: 106 additions & 58 deletions doc/usr/en/mod-install.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,70 +13,58 @@ title: Kernel Modules Installation

1. [Introduction](#introduction)
2. [Requirements](#requirements)
3. [Installation](#installation)
1. [DKMS](#dkms)
2. [Kbuild](#kbuild)
1. [Valid kernels](#valid-kernels)
2. [Build Essentials](#build-essentials)
2. [Kernel Headers](#kernel-headers)
3. [Network interfaces](#network-interfaces)
4. [DKMS](#dkms)
5. [Ethtool](#ethtool)
3. [Downloading the Code](#downloading-the-code)
3. [Compilation and Installation](#compilation-and-installation)
1. [Installation via DKMS](#installation-via-dkms)
2. [Installation via Kbuild](#installation-via--kbuild)

## Introduction

Jool is four things:
Jool is four binaries:

1. Two <a href="https://en.wikipedia.org/wiki/Loadable_kernel_module" target="_blank">kernel modules</a> you can hook up to Linux. One of them is the SIIT implementation and the other one is the Stateful NAT64. They are the main components and all you need to get started; this document explains how to install them.
2. Two <a href="https://en.wikipedia.org/wiki/User_space" target="_blank">userspace</a> applications which can be used to configure each module. They have their own [installation document](usr-install.html).

When you put it that way, there is really nothing unusual about Jool's installation. But I figure some of our users might have no previous experience meddling with drivers, so this overview will serve as an introduction to at least give them an idea of what each step does.
1. Two [kernel modules](https://en.wikipedia.org/wiki/Loadable_kernel_module) you can hook up to Linux. One of them is the SIIT implementation and the other is the Stateful NAT64. They are the translating components and all you need to get started; this document explains how to install them.
2. Two [userspace](https://en.wikipedia.org/wiki/User_space) applications which can be used to configure each module. They have their own [installation document](usr-install.html).

## Requirements

First off, the computer that will be translating traffic needs a kernel (again, Linux) whose version is 3.0 to 3.15. Higher versions are probably fine, but we haven't tested them. We do not recommend using Linux 3.12 because of the reasons outlined <a href="https://github.com/NICMx/NAT64/issues/90" target="_blank">here</a>.
Because The are so many different Linux versions out there, distributing the modules' binaries is not feasible; you need to compile them yourself.

(In following console segments, `$` indicates the command can be executed freely; `#` means it requites admin privileges.)

### Valid kernels

Use the `uname -r` command to know your kernel version.
Jool supports kernels starting from Linux 3.0. Use `uname -r` to know your kernel version.

{% highlight bash %}
$ /bin/uname -r
3.5.0-45-generic
$ # OK, fine.
{% endhighlight %}

If you're just getting acquainted with IPv4/IPv6 Translation, some people have an easier time picturing the ordeal when the translator has two separate network interfaces (one to interact with IPv6 networks, one for IPv4 networks). This is not a requirement; you can get away with only one interface (by [dual stacking](mod-run-alternate.html) on it), and you can also have more than one per protocol. This is possible because figuring out which interface should a packet be dispatched through is routing's problem, which is already well implemented in the kernel.
### Build Essentials

Because the tutorials are first and foremost a tool to get newcomers on the right mindset, most of the deployment discussion will assume two separate interfaces (exemplified below: eth0 and eth1).

{% highlight bash %}
$ /sbin/ip link show
(...)
2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 08:00:27:3d:24:77 brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 08:00:27:ca:18:c8 brd ff:ff:ff:ff:ff:ff
{% endhighlight %}

Finally, you need the dependencies. Pick whichever works for you...
Several distributions already include them; omit this step in those cases.

<div class="distro-menu">
<span class="distro-selector" onclick="showDistro(this);">Ubuntu</span>
<span class="distro-selector" onclick="showDistro(this);">Debian</span>
<span class="distro-selector" onclick="showDistro(this);">CentOS</span>
<span class="distro-selector" onclick="showDistro(this);">Arch Linux</span>
<span class="distro-selector" onclick="showDistro(this);">openSUSE</span>
<span class="distro-selector" onclick="showDistro(this);">Raspberry Pi</span>
</div>

<!-- Ubuntu -->
{% highlight bash %}
# apt-get install linux-headers-$(uname -r)
{% endhighlight %}

<!-- Debian -->
{% highlight bash %}
# apt-get install build-essential
# apt-get install linux-headers-$(uname -r)
{% endhighlight %}

<!-- CentOS -->
{% highlight bash %}
# yum install kernel-devel
# yum install kernel-headers
# yum install gcc
{% endhighlight %}

Expand All @@ -88,71 +76,131 @@ Finally, you need the dependencies. Pick whichever works for you...
<!-- openSUSE -->
{% highlight bash %}
# zypper install gcc make
{% endhighlight %}

### Kernel headers

All kernel modules depend on them; they tell Jool the parameters Linux was compiled with. Most distros host them in their repositories.

<div class="distro-menu">
<span class="distro-selector" onclick="showDistro(this);">Ubuntu/Debian</span>
<span class="distro-selector" onclick="showDistro(this);">CentOS</span>
<span class="distro-selector" onclick="showDistro(this);">openSUSE</span>
<span class="distro-selector" onclick="showDistro(this);">Raspberry Pi</span>
</div>

<!-- Ubuntu/Debian -->
{% highlight bash %}
# apt-get install linux-headers-$(uname -r)
{% endhighlight %}

<!-- CentOS -->
{% highlight bash %}
# yum install kernel-devel
# yum install kernel-headers
{% endhighlight %}

<!-- openSUSE -->
{% highlight bash %}
# zypper install kernel-source
{% endhighlight %}

<!-- Raspberry Pi -->
{% highlight bash %}
$ # see https://github.com/NICMx/NAT64/issues/158
$ # See https://github.com/NICMx/NAT64/issues/158
{% endhighlight %}

## Installation
### Network interfaces

Each kernel version combined with each different architecture requires different binaries, so providing packages for every combination would be impossibly cumbersome. For this reason, what you'll download is the source; there is no way around compiling the code yourself.
[Translating packets using only one interface is possible](mod-run-alternate.html), but two (one for IPv4, one for IPv6) is more intuitive.

On the flip side, kernel modules cannot have dependencies other than your kernel headers and a good compiler, so the procedure is fairly painless.
Therefore, if you're using these documents for educational purposes, two interfaces are recommended:

To download Jool, you have two options:
{% highlight bash %}
$ /sbin/ip link show
(...)
2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 08:00:27:3d:24:77 brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 08:00:27:ca:18:c8 brd ff:ff:ff:ff:ff:ff
{% endhighlight %}

* Official releases are hosted in the [Download page](download.html). These will prove less convoluted when you're installing the userspace application.
* There's the <a href="https://github.com/NICMx/NAT64" target="_blank">Github repository</a>. This might have slight bugfixes not present in the latest official release, which you can access by sticking to the latest commit of the master branch (in case you're wondering, we do all the risky development elsewhere).
### DKMS

DKMS is a framework for kernel module management. It's optional but recommended (reasons at [Compilation and Installation](#compilation-and-installation)).

{% highlight bash %}
# apt-get install dkms
{% endhighlight %}

## Getting the code

You have two options:

1. Official releases are hosted in the [Download page](download.html).
These will prove less convoluted when you install the userspace application.
2. There's the <a href="https://github.com/NICMx/NAT64" target="_blank">Github repository</a>.
This might have slight bugfixes not present in the latest official release, which you can access by sticking to the latest commit of the master branch (we do all the risky development elsewhere).

## Compilation and Installation

You might be used to a standard three-step procedure to compile and install programs: `./configure && make && make install`. Kernel modules do not follow it, but have a special one on their own called Kbuild.

If your distribution supports the Dynamic Kernel Module Support (DKMS) framework, this can be used in order to compile and build the Jool kernel modules. If however your distribution does not support DKMS, or its use is undesired for some reason, the Jool kernel modules can be built and installed manually by using the Kbuild system directly.

Regardless of which method you use to install the kernel modules, after a successfull installation you will be able to start Jool using `modprobe jool` or `modprobe jool_siit`. The logical next step after that would be to read the [Basic SIIT Tutorial](mod-run-vanilla.html).

### DKMS
### Installation via DKMS

The DKMS framework provides a convenient wrapper around the standard kernel Kbuild system. A single DKMS command will perform all the steps necessary in order to use third-party kernel modules such as Jool. It will also ensure that everything is done all over again whenever necessary (such as after a kernel upgrade). DKMS can also be used to create packages for deb/rpm-based distributions containing pre-built Jool kernel modules.

In order to install the Jool kernel modules using DKMS, you need to run `dkms install /path/to/Jool-sourcedir`, like so:

<div class="distro-menu">
<span class="distro-selector" onclick="showDistro(this);">Official version</span>
<span class="distro-selector" onclick="showDistro(this);">Github version</span>
</div>

{% highlight bash %}
$ unzip Jool-<version>.zip
# dkms install Jool-<version>
{% endhighlight %}

{% highlight bash %}
user@node:~# apt-get install dkms
user@node:~$ unzip Jool-<version>.zip
user@node:~# dkms install Jool-<version>
$ unzip NAT64-master.zip
# dkms install NAT64-master
{% endhighlight %}

DKMS will now have compiled, installed and indexed the Jool kernel modules; Jool is now ready for use.

### Kbuild
### Installation via Kbuild

Kbuild is the Linux kernel's standard system for compiling and installing kernel modules. Jool comes with native Kbuild support.

Kbuild is the Linux kernel's standard system for compiling and installing kernel modules. Jool comes with native Kbuild support. As far as the compilation goes, there is no `configure` script. But you also don't have to edit the Makefile; you jump straight to `make` and you're done. The global Makefile can be found in the `mod` folder:
<div class="distro-menu">
<span class="distro-selector" onclick="showDistro(this);">Official version</span>
<span class="distro-selector" onclick="showDistro(this);">Github version</span>
</div>

{% highlight bash %}
user@node:~$ unzip Jool-<version>.zip
user@node:~$ cd Jool-<version>/mod
user@node:~/Jool-<version>/mod$ make
$ unzip Jool-<version>.zip
$ cd Jool-<version>/mod
$ make
# make install
{% endhighlight %}

The Jool kernel modules are now compiled for your current kernel. Next, copy them to your system's module pool by running the `modules_install` target:

{% highlight bash %}
user@node:~/Jool-<version>/mod# make modules_install
$ unzip NAT64-master.zip
$ cd NAT64-master/mod
$ make
# make install
{% endhighlight %}

> **Warning!**
>
> Kernels 3.7 and up want you to sign your kernel modules to make sure you're loading them in a responsible manner.
>
> But if your kernel was not configured to _require_ this feature (the kernels of many distros don't), you won't have much of an issue here. The output of `make modules_install` will output "Can't read private key"; this looks like an error, but is actually a warning, <a href="https://github.com/NICMx/NAT64/issues/94#issuecomment-45248942" target="_blank">so you can continue the installation peacefully</a>.
> But if your kernel was not configured to _require_ this feature (the kernels of many distros don't), you won't have much of an issue here. The output of `make install` will output "Can't read private key"; this looks like an error, but is actually a warning, <a href="https://github.com/NICMx/NAT64/issues/94#issuecomment-45248942" target="_blank">so you can continue the installation peacefully</a>.
>
> Sorry; if your kernel _was_ compiled to require module signing, you probably know what you're doing, so I'll skip the instructions to make that work.
You'll later activate the modules using the `modprobe` command. Thing is, the fact that they reside in your pool doesn't mean they have already been indexed. Use `depmod` to make `modprobe` aware of the new modules:

{% highlight bash %}
user@node:~# /sbin/depmod
{% endhighlight %}
32 changes: 23 additions & 9 deletions doc/usr/en/usr-flags-atomic.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ title: Atomic Fragments

## Overview

"Atomic fragments" are IPv6 packets which are not fragmented but still contain a (redundant) [Fragment Header](https://tools.ietf.org/html/rfc2460#section-4.5). They are a hack in the NAT64 specification that intends to leverage the difference between the IPv4 minimum MTU (68) and the IPv6 minimum MTU (1280).
"Atomic fragments" are IPv6 packets which are not fragmented but still contain a (redundant) [Fragment Header](https://tools.ietf.org/html/rfc2460#section-4.5). They are a hack in the IP/ICMP Translation specification that intends to leverage the difference between the IPv4 minimum MTU (68) and the IPv6 minimum MTU (1280).

Atomic fragments are known to have [security implications](https://tools.ietf.org/html/rfc6946) and there is [official ongoing effort to deprecate them]({{ site.draft-deprecate-atomfrag-generation }}). Even RFC 6145 (ie. SIIT's core document) warns about [issues regarding the hack](http://tools.ietf.org/html/rfc6145#section-6).

Expand Down Expand Up @@ -118,9 +118,19 @@ Also see [`--boostMTU`](#boostmtu) for an important gotcha.
- Modes: Both (SIIT and Stateful)
- Translation direction: IPv4 to IPv6

If this is ON, Jool will always generate an "IPv6 Fragment Header" if the incoming IPv4 Packet does not set the DF flag.
In pseudocode form:

If this is OFF, then Jool will not generate the "IPv6 Fragment Header" whether the Flag of the incoming IPv4 Packet is set or not set, unless the incoming packet is a fragment, the "IPv6 Fragment Header" will be generated.
If the incoming IPv4 packet is a fragment:
The outgoing IPv6 packet will be a fragment.
(And will therefore include a Fragment Header.)
Else:
If the DF flag is ON:
The outgoing packet will not include a Fragment Header.
Else:
If --genFH is ON:
The outgoing packet will include a Fragment Header.
Else:
The outgoing packet will not include a Fragment Header.

This is the flag that causes Linux to flip out when it needs to fragment. It's broken, so activate at your own risk.

Expand All @@ -132,14 +142,19 @@ This is the flag that causes Linux to flip out when it needs to fragment. It's b
- Modes: Both (SIIT and Stateful)
- Translation direction: IPv6 to IPv4

All IPv4 packets contain an Identification field. IPv6 packets only contain an Identification field if they have a Fragment header.
IPv6 packets only contain an fragment identifier field if they contain a Fragment Header. All IPv4 packets contain a fragment identifier field.

If the incoming IPv6 packet has a fragment header, the <a href="http://en.wikipedia.org/wiki/IPv4#Header" target="_blank">IPv4 header</a>'s Identification field is _always_ copied from the low-order bits of the IPv6 fragment header's Identification value.
This flag dictates how this value should be set when a packet lacking identifier is being translated to IPv4.

Otherwise:
In pseudocode form:

- If `--genID` is OFF, the IPv4 header's Identification fields are set to zero.
- If `--genID` is ON, the IPv4 headers' Identification fields are set randomly.
If the incoming packet has a Fragment Header:
The fragment identifier is copied.
Else:
If --genID is ON:
The fragment identifier will be set randomly.
Else:
The fragment identifier will be zero.

### `--boostMTU`

Expand Down Expand Up @@ -176,4 +191,3 @@ Notice, if `--setDF` and `--boostMTU` are both ON and there's an IPv4 link with
4. Jool translates it to ICMPv6 _Packet Too Big_ with MTU=1280.
5. Goto 1.

Thanks to Tore Anderson for noticing (and mostly writing) this quirk.
Loading

0 comments on commit 7416267

Please sign in to comment.