交叉编译器 arm-linux-gnueabi 和 arm-linux-gnueabihf 的区别

自己之前一直没搞清楚这两个交叉编译器到底有什么问题,特意google一番,总结如下,希望能帮到道上和我有同样困惑的兄弟…..

一. 什么是ABI和EABI
1) ABI: 二进制应用程序接口(Application Binary Interface (ABI) for the ARM Architecture)
在计算机中,应用二进制接口描述了应用程序(或者其他类型)和操作系统之间或其他应用程序的低级接口.
ABI涵盖了各种细节,如:
数据类型的大小、布局和对齐;
调用约定(控制着函数的参数如何传送以及如何接受返回值),例如,是所有的参数都通过栈传递,还是部分参数通过寄存器传递;哪个寄存器用于哪个函数参数;通过栈传递的第一个函数参数是最先push到栈上还是最后;
系统调用的编码和一个应用如何向操作系统进行系统调用;
以及在一个完整的操作系统ABI中,目标文件的二进制格式、程序库等等。
一个完整的ABI,像Intel二进制兼容标准 (iBCS) ,允许支持它的操作系统上的程序不经修改在其他支持此ABI的操作体统上运行。
ABI不同于应用程序接口(API),API定义了源代码和库之间的接口,因此同样的代码可以在支持这个API的任何系统中编译,ABI允许编译好的目标代码在使用兼容ABI的系统中无需改动就能运行。

2) EABI: 嵌入式ABI
嵌入式应用二进制接口指定了文件格式、数据类型、寄存器使用、堆积组织优化和在一个嵌入式软件中的参数的标准约定。
开发者使用自己的汇编语言也可以使用EABI作为与兼容的编译器生成的汇编语言的接口。
支持EABI的编译器创建的目标文件可以和使用类似编译器产生的代码兼容,这样允许开发者链接一个由不同编译器产生的库。
EABI与关于通用计算机的ABI的主要区别是应用程序代码中允许使用特权指令,不需要动态链接(有时是禁止的),和更紧凑的堆栈帧组织用来节省内存。广泛使用EABI的有Power PC和ARM.

二. gnueabi相关的两个交叉编译器: gnueabi和gnueabihf
在debian源里这两个交叉编译器的定义如下:
gcc-arm-linux-gnueabi – The GNU C compiler for armel architecture
gcc-arm-linux-gnueabihf – The GNU C compiler for armhf architecture
可见这两个交叉编译器适用于armel和armhf两个不同的架构, armel和armhf这两种架构在对待浮点运算采取了不同的策略(有fpu的arm才能支持这两种浮点运算策略)

其实这两个交叉编译器只不过是gcc的选项-mfloat-abi的默认值不同. gcc的选项-mfloat-abi有三种值soft,softfp,hard(其中后两者都要求arm里有fpu浮点运算单元,soft与后两者是兼容的,但softfp和hard两种模式互不兼容):
soft : 不用fpu进行浮点计算,即使有fpu浮点运算单元也不用,而是使用软件模式。
softfp : armel架构(对应的编译器为gcc-arm-linux-gnueabi)采用的默认值,用fpu计算,但是传参数用普通寄存器传,这样中断的时候,只需要保存普通寄存器,中断负荷小,但是参数需要转换成浮点的再计算。
hard : armhf架构(对应的编译器gcc-arm-linux-gnueabihf)采用的默认值,用fpu计算,传参数也用fpu中的浮点寄存器传,省去了转换, 性能最好,但是中断负荷高。

把以下测试使用的c文件内容保存成mfloat.c:

include <stdio.h>

int main(void)
{
double a,b,c;
a = 23.543;
b = 323.234;
c = b/a;
printf(“the 13/2 = %fn”, c);
printf(“hello world !n”);
return 0;
}

1)使用arm-linux-gnueabihf-gcc编译,使用“-v”选项以获取更详细的信息:

arm-linux-gnueabihf-gcc -v mfloat.c

COLLECT_GCC_OPTIONS=’-v’ ‘-march=armv7-a’ ‘-mfloat-abi=hard’ ‘-mfpu=vfpv3-d16′ ‘-mthumb’
-mfloat-abi=hard,可看出使用hard硬件浮点模式。

2)使用arm-linux-gnueabi-gcc编译:

arm-linux-gnueabi-gcc -v mfloat.c

COLLECT_GCC_OPTIONS=’-v’ ‘-march=armv7-a’ ‘-mfloat-abi=softfp’ ‘-mfpu=vfpv3-d16′ ‘-mthumb’
-mfloat-abi=softfp,可看出使用softfp模式。

三. 拓展阅读
下文阐述了ARM代码编译时的软浮点(soft-float)和硬浮点(hard-float)的编译以及链接实现时的不同。从VFP浮点单元的引入到软浮点(soft-float)和硬浮点(hard-float)的概念

VFP (vector floating-point)
从ARMv5开始,就有可选的 Vector Floating Point (VFP) 模块,当然最新的如 Cortex-A8, Cortex-A9 和 Cortex-A5 可以配置成不带VFP的模式供芯片厂商选择。
VFP经过若干年的发展,有VFPv2 (一些 ARM9 / ARM11)、 VFPv3-D16(只使用16个浮点寄存器,默认为32个)和VFPv3+NEON (如大多数的Cortex-A8芯片) 。对于包含NEON的ARM芯片,NEON一般和VFP公用寄存器。

硬浮点Hard-float
编译器将代码直接编译成发射给硬件浮点协处理器(浮点运算单元FPU)去执行。FPU通常有一套额外的寄存器来完成浮点参数传递和运算。
使用实际的硬件浮点运算单元FPU当然会带来性能的提升。因为往往一个浮点的函数调用需要几个或者几十个时钟周期。

软浮点 Soft-float
编译器把浮点运算转换成浮点运算的函数调用和库函数调用,没有FPU的指令调用,也没有浮点寄存器的参数传递。浮点参数的传递也是通过ARM寄存器或者堆栈完成。
现在的Linux系统默认编译选择使用hard-float,即使系统没有任何浮点处理器单元,这就会产生非法指令和异常。因而一般的系统镜像都采用软浮点以兼容没有VFP的处理器。

armel ABI和armhf ABI
在armel中,关于浮点数计算的约定有三种。以gcc为例,对应的-mfloat-abi参数值有三个:soft,softfp,hard。
soft是指所有浮点运算全部在软件层实现,效率当然不高,会存在不必要的浮点到整数、整数到浮点的转换,只适合于早期没有浮点计算单元的ARM处理器;
softfp是目前armel的默认设置,它将浮点计算交给FPU处理,但函数参数的传递使用通用的整型寄存器而不是FPU寄存器;
hard则使用FPU浮点寄存器将函数参数传递给FPU处理。
需要注意的是,在兼容性上,soft与后两者是兼容的,但softfp和hard两种模式不兼容。
默认情况下,armel使用softfp,因此将hard模式的armel单独作为一个abi,称之为armhf。
而使用hard模式,在每次浮点相关函数调用时,平均能节省20个CPU周期。对ARM这样每个周期都很重要的体系结构来说,这样的提升无疑是巨大的。
在完全不改变源码和配置的情况下,在一些应用程序上,使用armhf能得到20%——25%的性能提升。对一些严重依赖于浮点运算的程序,更是可以达到300%的性能提升。

Soft-float和hard-float的编译选项
在CodeSourcery gcc的编译参数上,使用-mfloat-abi=name来指定浮点运算处理方式。-mfpu=name来指定浮点协处理的类型。
可选类型如fpa,fpe2,fpe3,maverick,vfp,vfpv3,vfpv3-fp16,vfpv3-d16,vfpv3-d16-fp16,vfpv3xd,vfpv3xd-fp16,neon,neon-fp16,vfpv4,vfpv4-d16,fpv4-sp-d16,neon-vfpv4等。
使用-mfloat-abi=hard (等价于-mhard-float) -mfpu=vfp来选择编译成硬浮点。使用-mfloat-abi=softfp就能兼容带VFP的硬件以及soft-float的软件实现,运行时的连接器ld.so会在执行浮点运算时对于运算单元的选择,
是直接的硬件调用还是库函数调用,是执行/lib还是/lib/vfp下的libm。-mfloat-abi=soft (等价于-msoft-float)直接调用软浮点实现库。

在ARM RVCT工具链下,定义fpu模式:
–fpu softvfp
–fpu softvfp+vfpv2
–fpu softvfp+vfpv3
–fpu softvfp+vfpv_fp16
–fpu softvfp+vfpv_d16
–fpu softvfp+vfpv_d16_fp16.

定义浮点运算类型
–fpmode ieee_full : 所有单精度float和双精度double的精度都要和IEEE标准一致,具体的模式可以在运行时动态指定;
–fpmode ieee_fixed : 舍入到最接近的实现的IEEE标准,不带不精确的异常;
–fpmode ieee_no_fenv :舍入到最接近的实现的IEEE标准,不带异常;
–fpmode std :非规格数flush到0、舍入到最接近的实现的IEEE标准,不带异常;
–fpmode fast : 更积极的优化,可能会有一点精度损失。

原文链接:https://www.veryarm.com/296.html

命名规则

交叉编译工具链的命名规则为:arch [-vendor] [-os] [-(gnu)eabi]

  • arch 体系架构,如ARM,MIPS
  • vendor 工具链提供商
  • os 目标操作系统
  • eabi 嵌入式应用二进制接口(Embedded Application Binary Interface)

根据对操作系统的支持与否,ARM GCC可分为支持和不支持操作系统,如

arm-none-eabi:这个是没有操作系统的,自然不可能支持那些跟操作系统关系密切的函数,比如fork(2)。他使用的是newlib这个专用于嵌入式系统的C库。
arm-none-linux-eabi:用于Linux的,使用Glibc

arm-none-eabi-gcc

(ARM architecture,no vendor,not target an operating system,complies with the ARM EABI)
用于编译 ARM 架构的裸机系统(包括 ARM Linux 的 boot、kernel,不适用编译 Linux 应用 Application),一般适合 ARM7、Cortex-M 和 Cortex-R 内核的芯片使用,所以不支持那些跟操作系统关系密切的函数,比如fork(2),他使用的是 newlib 这个专用于嵌入式系统的C库。

arm-none-linux-gnueabi-gcc

(ARM architecture, no vendor, creates binaries that run on the Linux operating system, and uses the GNU EABI)

主要用于基于ARM架构的Linux系统,可用于编译 ARM 架构的 u-boot、Linux内核、linux应用等。arm-none-linux-gnueabi基于GCC,使用Glibc库,经过 Codesourcery 公司优化过推出的编译器。arm-none-linux-gnueabi-xxx 交叉编译工具的浮点运算非常优秀。一般ARM9、ARM11、Cortex-A 内核,带有 Linux 操作系统的会用到。

arm-eabi-gcc

Android ARM 编译器。

armcc

ARM 公司推出的编译工具,功能和 arm-none-eabi 类似,可以编译裸机程序(u-boot、kernel),但是不能编译 Linux 应用程序。armcc一般和ARM开发工具一起,Keil MDK、ADS、RVDS和DS-5中的编译器都是armcc,所以 armcc 编译器都是收费的(爱国版除外,呵呵~~)。

arm-none-uclinuxeabi-gcc 和 arm-none-symbianelf-gcc

arm-none-uclinuxeabi 用于uCLinux,使用Glibc。

arm-none-symbianelf 用于symbian,没用过,不知道C库是什么 。

Codesourcery

Codesourcery推出的产品叫Sourcery G++ Lite Edition,其中基于command-line的编译器是免费的,在官网上可以下载,而其中包含的IDE和debug 工具是收费的,当然也有30天试用版本的。

目前CodeSourcery已经由明导国际(Mentor Graphics)收购,所以原本的网站风格已经全部变为 Mentor 样式,但是 Sourcery G++ Lite Edition 同样可以注册后免费下载。

Codesourcery一直是在做ARM目标 GCC 的开发和优化,它的ARM GCC在目前在市场上非常优秀,很多 patch 可能还没被gcc接受,所以还是应该直接用它的(而且他提供Windows下[mingw交叉编译的]和Linux下的二进制版本,比较方便;如果不是很有时间和兴趣,不建议下载 src 源码包自己编译,很麻烦,Codesourcery给的shell脚本很多时候根本没办法直接用,得自行提取关键的部分手工执行,又费精力又费时间,如果想知道细节,其实不用自己编译一遍,看看他是用什么步骤构建的即可,如果你对交叉编译器感兴趣的话。

ABI 和 EABI

ABI:二进制应用程序接口(Application Binary Interface (ABI) for the ARM Architecture)。在计算机中,应用二进制接口描述了应用程序(或者其他类型)和操作系统之间或其他应用程序的低级接口。

EABI:嵌入式ABI。嵌入式应用二进制接口指定了文件格式、数据类型、寄存器使用、堆积组织优化和在一个嵌入式软件中的参数的标准约定。开发者使用自己的汇编语言也可以使用 EABI 作为与兼容的编译器生成的汇编语言的接口。

两者主要区别是,ABI是计算机上的,EABI是嵌入式平台上(如ARM,MIPS等)。

arm-linux-gnueabi-gcc 和 arm-linux-gnueabihf-gcc

两个交叉编译器分别适用于 armel 和 armhf 两个不同的架构,armel 和 armhf 这两种架构在对待浮点运算采取了不同的策略(有 fpu 的 arm 才能支持这两种浮点运算策略)。

其实这两个交叉编译器只不过是 gcc 的选项 -mfloat-abi 的默认值不同。gcc 的选项 -mfloat-abi 有三种值 soft、softfp、hard(其中后两者都要求 arm 里有 fpu 浮点运算单元,soft 与后两者是兼容的,但 softfp 和 hard 两种模式互不兼容):
soft: 不用fpu进行浮点计算,即使有fpu浮点运算单元也不用,而是使用软件模式。
softfp: armel架构(对应的编译器为 arm-linux-gnueabi-gcc )采用的默认值,用fpu计算,但是传参数用普通寄存器传,这样中断的时候,只需要保存普通寄存器,中断负荷小,但是参数需要转换成浮点的再计算。
hard: armhf架构(对应的编译器 arm-linux-gnueabihf-gcc )采用的默认值,用fpu计算,传参数也用fpu中的浮点寄存器传,省去了转换,性能最好,但是中断负荷高。

把以下测试使用的C文件内容保存成 mfloat.c:

include <stdio.h>

int main(void)
{

double a,b,c;
a = 23.543;
b = 323.234;
c = b/a;
printf(“the 13/2 = %f\n”, c);
printf(“hello world !\n”);
return 0;

}

1、使用 arm-linux-gnueabihf-gcc 编译,使用“-v”选项以获取更详细的信息:

arm-linux-gnueabihf-gcc -v mfloat.c

COLLECT_GCC_OPTIONS=’-v’ ‘-march=armv7-a’ ‘-mfloat-abi=hard’ ‘-mfpu=vfpv3-d16′ ‘-mthumb’
-mfloat-abi=hard

可看出使用hard硬件浮点模式。

2、使用 arm-linux-gnueabi-gcc 编译:

arm-linux-gnueabi-gcc -v mfloat.c

COLLECT_GCC_OPTIONS=’-v’ ‘-march=armv7-a’ ‘-mfloat-abi=softfp’ ‘-mfpu=vfpv3-d16′ ‘-mthumb’
-mfloat-abi=softfp

可看出使用softfp模式。

交叉编译工具

参考资料

交叉编译器 arm-linux-gnueabi 和 arm-linux-gnueabihf 的区别:http://www.cnblogs.com/xiaotlili/p/3306100.html
arm-none-linux-gnueabi,arm-none-eabi 与arm-eabi 区别:http://blog.csdn.net/mantis_1984/article/details/21049273
What's the difference between arm-linux- / arm-none-linux-gnueabi- / arm-fsl-linux-gnueabi- in LTIB?https://community.freescale.com/thread/313490

sudo supernode /etc/n2n/supernode.conf &
sudo edge /etc/n2n/edge.conf

supercode -l <port> &
edge -a <local ip> -c n2n -l <host:port> -k <password>
/etc/default/n2n

/etc/n2n/edge.conf.sample

#
#         The configuration file is similar to the command line, with one option per line. An equal
#        sign '=' should be used between key and value. Example: -c=mynetwork or --community=mynetwork
#        This file contains a basic configuration example, please refer to the help (-h) for the full
#        list of available options.
#
#       -d|--tun-device
#        Specifies the name of the TUN interface. 
#
-d=n2n0
#
#       -c|--community
#        Specifies the n2n community name the edge belongs to.
#
-c=mynetwork
#
#       -k
#        Sets the encryption key (ASCII). The environment variable N2N_KEY=<key> can also be used. 
#
-k=mypassword
#
#       -m
#        Specified the MAC address for the TAP interface (random otherwise).
#
# -m=DE:AD:BE:EF:99:99
#
#       -a
#        Sets the interface address. For DHCP use '-r -a dhcp:0.0.0.0'.
#
-a=1.2.3.4
#
#       -p
#        Sets the local UDP port to a fixed port.
#
-p=50001
#
#       -l|--supernode-list
#        Specifies the supernode IP and port.
#
-l=7.8.9.0:7777
#

supernode.conf.sample

#
#        The configuration file is similar to the command line, with one option per line. An equal
#        sign '=' should be used between key and value. Example: -l=7777 or --local-port=7777
#        This file contains a basic configuration example, please refer to the help (-h) for the full
#        list of available options.
#
#       -l|--local-port
#        Sets the UDP listening port. 
#
# -l=7777
#
# Specify in supernodes.list the list of allowed communities
#
# -c=supernodes.list

/etc/n2n/supernodes.list

# suppercodes list
<edge_Group>

 In order to use this repository do (as root):

    18.04 LTS
        apt-get install software-properties-common wget
        add-apt-repository universe [ unless you have done it previously ]
        wget http://apt.ntop.org/18.04/all/apt-ntop.deb
        apt install ./apt-ntop.deb 
    16.04 LTS
        wget http://apt.ntop.org/16.04/all/apt-ntop.deb
        apt install ./apt-ntop.deb 
    14.04 LTS
        wget http://apt.ntop.org/14.04/all/apt-ntop.deb
        dpkg -i apt-ntop.deb
        add-apt-repository ppa:maxmind/ppa 
    Debian 10 (buster)
        wget http://apt.ntop.org/buster/all/apt-ntop.deb
        apt install ./apt-ntop.deb 
    Debian 9 (stretch)
        wget http://apt.ntop.org/stretch/all/apt-ntop.deb
        apt install ./apt-ntop.deb 
    Debian 8 (jessie)
        wget http://apt.ntop.org/jessie/all/apt-ntop.deb
        dpkg -i apt-ntop.deb
        echo "deb http://archive.debian.org/debian jessie-backports main" >> /etc/apt/sources.list
        echo 'Acquire::Check-Valid-Until no;' > /etc/apt/apt.conf.d/99no-check-valid-until
        apt-get update && apt-get install libjson-c2 
    Raspbian (stretch_pi)
        echo "deb http://apt.ntop.org/stretch_pi armhf/" > /etc/apt/sources.list.d/ntop.list
        echo "deb http://apt.ntop.org/stretch_pi all/" >> /etc/apt/sources.list.d/ntop.list 

N2N

N2n is a light VPN software which make it easy to create virtual networks bypassing intermediate firewalls.

In order to start using N2N, two elements are required:

  • A supernode: it allows edge nodes to announce and discover other nodes. It must have a port publicly accessible on internet.
  • Edge nodes: the nodes which will be part of the virtual networks

A virtual network shared between multiple edge nodes in n2n is called a community. A single supernode can relay multiple communities and a single PC can be part of multiple communities at the same time. An encryption key can be used by the edge nodes to encrypt the packets within their community.

N2n tries to enstablish a direct P2P connection between the edge nodes when possible. When this is not possible (usually due to special NAT devices), the supernode is also used to relay the packets.

Quick Setup

Some linux distributions already provide n2n as a package so a simple sudo apt-get install n2n will do the work. Alternatively, up to date packages for most distributions are available on ntop repositories.

On host1 run:

$ sudo edge -c mynetwork -k mysecretpass -a 192.168.100.1 -f -l supernode.ntop.org:7777

On host2 run:

$ sudo edge -c mynetwork -k mysecretpass -a 192.168.100.2 -f -l supernode.ntop.org:7777

Now the two hosts can ping each other.

IMPORTANT It is strongly adviced to choose a custom community name (-c) and a secret encryption key (-k) in order to prevent other users to connect to your PC. For privacy and to reduce the above server load, it is also suggested to set up a custom supernode as exmplained below.

Setting up a custom Supernode

You can create your own infrastructure by setting up a supernode on a public server (e.g. a VPS). You just need to open a single port (1234 in the example below) on your firewall (usually iptables).

  1. Install the n2n package
  2. Edit /etc/n2n/supernode.conf and add the following:
-l=1234
  1. Start the supernode service with sudo systemctl start supernode
  2. Optionally enable supernode start on boot: sudo systemctl enable supernode

Now the supernode service should be up and running on port 1234. On your edge nodes you can now specify -l your_supernode_ip:1234 to use it. All the edge nodes must use the same supernode.

Routing the traffic

On linux, n2n provides a standard TAP interface, so routing works gracefully via the standard system utilities as follows.

In this example host1 is the edge router (with n2n IP 192.168.100.1), whereas host2 is the client.

Here is how to configure host1:

  1. Add the -r option to the edge options to enable routing
  2. Enable packet forwarding with sudo sysctl -w net.ipv4.ip_forward=1
  3. Possibly configure iptables to ACCEPT the packets on the FORWARD chain.

On host2, run the edge program as normal to join the host1 community.

In order to forward all the internet traffic via host2:

# Determine the current gateway (e.g. 192.168.1.1)
$ ip route show default

# Add a route to reach the supernode via such gateway
$ sudo ip route add supernode.ntop.org via 192.168.1.1

# Forward all the internet traffic via host1
$ sudo ip route del default
$ sudo ip route add default via 192.168.100.1

This process can be greatly simplified by using the n2n_gateway.sh script.

See Routing.md for other use cases and in depth explanation.

Manual Compilation

On linux, compilation from source is straight forward:

./autogen.sh
./configure
make

# optionally install
make install

For Windows, check out Windows.md for compilation and run instuctions.

For MacOS, check out n2n_on_MacOS.txt.

Running edge as a service

edge can also be run as a service instead of cli:

  1. Edit /etc/n2n/edge.conf with your custom options. See /etc/n2n/edge.conf.sample.
  2. Start the service: sudo systemctl start edge
  3. Optionally enable edge start on boot: sudo systemctl enable edge

You can run multiple edge service instances by creating /etc/n2n/edge-instance1.conf and
starting it with sudo systemctl start edge@instance1.

IPv6 Support

N2n can tunnel IPv6 traffic into the virtual network but does not support
IPv6 for edge-to-supernode communication yet.

Check out IPv6.md for more information.

Security considerations

n2n edge nodes use twofish encryption by default for compatibility reasons with existing versions.

IMPORTANT Encryption is only applied to the packet payload. Some metadata like the virtual MAC address
of the edge nodes, their IP address and the community are sent in cleartext.

When encryption is enabled, the supernode will not be able to decrypt the traffic exchanged between
two edge nodes, but it will now that edge A is talking with edge B.

Recently AES encryption support has been implemented, which increases both security and performance,
so it is recommended to enable it on all the edge nodes by specifying the -A option.

A benchmark of the encryption methods is available when compiled from source with tools/n2n-benchmark.

Contribution

You can contribute to n2n in variuos ways:

  • Update an open issue or create a new one with detailed information
  • Propose new features
  • Improve the documentation
  • Provide pull requests with enhancenents

For details about the internals of n2n check out Hacking guide.

Related Projects

Here is a list of third-party projects connected to this repository.


(C) 2007-2019 - ntop.org and contributors

ntop/n2n
code
binary packages
N2n Gui En
n2n手机版

N2N

N2n is a light VPN software which make it easy to create virtual networks bypassing intermediate firewalls.

In order to start using N2N, two elements are required:

A supernode: it allows edge nodes to announce and discover other nodes. It must have a port publicly accessible on internet.

Edge nodes: the nodes which will be part of the virtual networks

A virtual network shared between multiple edge nodes in n2n is called a community. A single supernode can relay multiple communities and a single PC can be part of multiple communities at the same time. An encryption key can be used by the edge nodes to encrypt the packets within their community.

N2n tries to enstablish a direct P2P connection between the edge nodes when possible. When this is not possible (usually due to special NAT devices), the supernode is also used to relay the packets.
Quick Setup

Some linux distributions already provide n2n as a package so a simple sudo apt-get install n2n will do the work. Alternatively, up to date packages for most distributions are available on ntop repositories.

On host1 run:

$ sudo edge -c mynetwork -k mysecretpass -a 192.168.100.1 -f -l supernode.ntop.org:7777

On host2 run:

$ sudo edge -c mynetwork -k mysecretpass -a 192.168.100.2 -f -l supernode.ntop.org:7777

Now the two hosts can ping each other.

IMPORTANT It is strongly adviced to choose a custom community name (-c) and a secret encryption key (-k) in order to prevent other users to connect to your PC. For privacy and to reduce the above server load, it is also suggested to set up a custom supernode as exmplained below.
Setting up a custom Supernode

You can create your own infrastructure by setting up a supernode on a public server (e.g. a VPS). You just need to open a single port (1234 in the example below) on your firewall (usually iptables).

Install the n2n package
Edit /etc/n2n/supernode.conf and add the following:

-l=1234

Start the supernode service with sudo systemctl start supernode
Optionally enable supernode start on boot: sudo systemctl enable supernode

Now the supernode service should be up and running on port 1234. On your edge nodes you can now specify -l your_supernode_ip:1234 to use it. All the edge nodes must use the same supernode.
Routing the traffic

On linux, n2n provides a standard TAP interface, so routing works gracefully via the standard system utilities as follows.

In this example host1 is the edge router (with n2n IP 192.168.100.1), whereas host2 is the client.

Here is how to configure host1:

Add the -r option to the edge options to enable routing
Enable packet forwarding with sudo sysctl -w net.ipv4.ip_forward=1
Possibly configure iptables to ACCEPT the packets on the FORWARD chain.

On host2, run the edge program as normal to join the host1 community.

In order to forward all the internet traffic via host2:

Determine the current gateway (e.g. 192.168.1.1)

$ ip route show default

Add a route to reach the supernode via such gateway

$ sudo ip route add supernode.ntop.org via 192.168.1.1

Forward all the internet traffic via host1

$ sudo ip route del default
$ sudo ip route add default via 192.168.100.1

This process can be greatly simplified by using the n2n_gateway.sh script.

See Routing.md for other use cases and in depth explanation.
Manual Compilation

On linux, compilation from source is straight forward:

./autogen.sh
./configure
make

optionally install

make install

For Windows, check out Windows.md for compilation and run instuctions.

For MacOS, check out n2n_on_MacOS.txt.
Running edge as a service

edge can also be run as a service instead of cli:

Edit /etc/n2n/edge.conf with your custom options. See /etc/n2n/edge.conf.sample.
Start the service: sudo systemctl start edge
Optionally enable edge start on boot: sudo systemctl enable edge

You can run multiple edge service instances by creating /etc/n2n/edge-instance1.conf and starting it with sudo systemctl start edge@instance1.
IPv6 Support

N2n can tunnel IPv6 traffic into the virtual network but does not support IPv6 for edge-to-supernode communication yet.

Check out IPv6.md for more information.
Security considerations

n2n edge nodes use twofish encryption by default for compatibility reasons with existing versions.

IMPORTANT Encryption is only applied to the packet payload. Some metadata like the virtual MAC address of the edge nodes, their IP address and the community are sent in cleartext.

When encryption is enabled, the supernode will not be able to decrypt the traffic exchanged between two edge nodes, but it will now that edge A is talking with edge B.

Recently AES encryption support has been implemented, which increases both security and performance, so it is recommended to enable it on all the edge nodes by specifying the -A option.

A benchmark of the encryption methods is available when compiled from source with tools/n2n-benchmark.
Contribution

You can contribute to n2n in variuos ways:

Update an open issue or create a new one with detailed information
Propose new features
Improve the documentation
Provide pull requests with enhancenents

For details about the internals of n2n check out Hacking guide.
Related Projects

Here is a list of third-party projects connected to this repository.

N2n for android: hin2n
N2n v1 and v2 version from meyerd: meyerd n2n
Docker images: DockerHub - DockerStore