Aus wiki.freifunk.net
Zur Navigation springenZur Suche springen
Developer Richard Andrews, Luca Deri
First released
Latest preview version
Release date and age
Frequently updated yes
Programming language C
Platform Gnu/Linux, Windows
Language English
Status active
Genre VPN Software
License GNU General Public License v3
Website http://www.ntop.org/products/n2n/
Download http://www.ntop.org/get-started/download/


n2n is a small layer 2 vpn based on the ideas of modern p2p systems. It creates only shared key security, which should be enough for freifunk purposes and has a very small flash footprint. Currently we use n2n Protocolversion 2.


pre-compiled v1 package for kamikaze (trunk 11600) can be installed via: ipkg install http://downloads.leo34.net/fonera/packages/n2n_svn3561-1_mips.ipk

fritjoff built a small kamikaze trunk package, to be improved: http://builder.frithjof-hammer.de/n2n/

packet b0rken, use:

Index: openwrt/kamikaze/Makefile
--- openwrt/kamikaze/Makefile   (revision 3558)
+++ openwrt/kamikaze/Makefile   (working copy)
@@ -1,9 +1,3 @@
-# Copyright (C) 2008 OpenWrt.org
-# This is free software, licensed under the GNU General Public License v2.
  include $(TOPDIR)/rules.mk

@@ -42,7 +36,7 @@

  define Build/Compile
-       $(MAKE) -C$(PKG_BUILD_DIR)
+       $(MAKE) CC="$(TARGET_CC)" -C $(PKG_BUILD_DIR)

To have proper integration for uci, please use these fragments


config "n2n" "edge"
        option ifname           'n2n'
        option ip4address       '77.87.48.x'
        option ip4netmask       ''
#       option ip6address       'fec0:babe:x/48'
        option community        'bbb'
        option key              'pass'
        option supernode        'vpn.berlin.freifunk.net:8718'
        option httptunnel       '0'
        option routing          '1'
        option verbose          '0'


#!/bin/sh /etc/rc.common


do_edge () {
        config_load n2n

        config_get dev edge ifname
        config_get ip4addr edge ip4address
        config_get ip4mask edge ip4netmask
        config_get community edge community
        config_get key edge key
        config_get supernode edge supernode
        config_get_bool httptunnel edge httptunnel
        config_get_bool routing edge routing
        config_get_bool verbose edge verbose


start() {
        include /lib/network
        config_load /var/state/network

        $EDGE -f -d $dev -a $ipv4 -c $community -k $key -l $supernode -t $httptunnel -r $routing -v $verbose

        #hack for n2n ticket #48
        ifconfig $dev $ip4addr netmask $ip4mask

stop () {
        killall edge

add the following to /etc/config/network

config interface n2n
        option ifname   n2n

deb based systems (debian, ubuntu)



# /etc/init.d/edge: start and stop the n2n edge



if test -f /etc/default/edge; then
    . /etc/default/edge

. /lib/lsb/init-functions

compile_opts() {
        if [ $HTTPTUNNEL = 1 ]; then EDGE_OPTS+=" -t"; fi
        if [ $ROUTING = 1 ]; then EDGE_OPTS+=" -r"; fi
        if [ $VERBOSE = 1 ]; then EDGE_OPTS+=" -v"; fi


case "$1" in
        echo -n "Starting n2n VPN daemon: edge"
#        echo $EDGE $EDGE_OPTS
        start-stop-daemon --start --quiet --exec $EDGE -- $EDGE_OPTS
        echo "."
        #fix IP Address
        #ifconfig $IFNAME $IP4ADDRESS
        echo -n "Stopping n2n VPN daemon: edge"
        start-stop-daemon --stop --quiet --exec $EDGE -- $EDGE_OPTS
        echo "."
        $0 stop
        $0 start

        echo "Usage: $0 {start|stop|restart}"
        exit 1

exit 0

Debian packages for n2n v1 with netmask patch:

Note: This package is not tested because I had no machine running Debian.
Seems to work properly on Debian Etch.


I've created a Port of n2n v1 for FreeBSD.
It already includes my subnet patch.
It's not merged with the official FreeBSD Ports repository but this will be done soon.

You can check out the latest revision at

Send your feedback to <syso-n2n(at)no-route.org> or create a new ticket if you've found a bug.


Supernode at vpn.berlin.freifunk.net, very secret password is "pass", community is bbb (case sensitive). We use this for connecting our CityMesh by VPN.

We use IP addresses of the range (host going from .65 - .126)

example startup line:

sudo ./edge -d bbb -c bbb -k pass -a static: -s -l vpn.berlin.freifunk.net:8718 -f -vvv

IP config

IPv4 addresses

Hosts from to

hostname IPv4-Address Admin email Comment
bbb1 dpaufler at leo34 dot net Main VPN Server BBB1
weimarnetz bittorf at bluebottle dot com http://weimarnetz.de/freifunk/vpn/
kel1 syso-ff at no-route dot org Temporaer fuer testzwecke.
c-base GW dpaufler at leo34 dot net, cven at cbase dot org GW @cbase (WCW2009)
gate dpaufler at leo34 dot net router @home
tetzlav-vhost tetzlav ät leipzig.freifunk.net qemu-openwrt @inet
tetzlav-ff-web tetzlav ät leipzig.freifunk.net server @home
berlin.freifunk.net nosy ät c-base.org berlin web/dns
Kortikalknoten pirat ät ralfgerlich dot de Viktoriastadt Titanic e.V.
J.A.S. pirat ät ralfgerlich dot de Viktoriastadt Kaskelstr.
Canapé pirat ät ralfgerlich dot de Südliche Pfarrstraße Berlin
bgp.ff.dd19.de dpaufler at leo34 dot net, alx at dd19 dot de BGP routing FistColo
carma dpaufler at leo34 dot net mobile notebook
alx alx at dd19 de FOKUS vpn gate
alx-eh2009 alx at dd19 de eh2009 vpn gate
morpheus simon.frerichs gmail com siit, ipv6, ipv4 :)
kifuse02 patrick lunatiki de pberg build & vpn server
druschba patrick lunatiki de Berlin Weißensee uplink (Umbenannt von "lachman" zu "druschba")
pitoresque joli64 web de pberg
rinocelot kinoletti gmail com pberg / kiezfunk ;)
blackhole freifunk at animatedpictures de
karow mercurix at wlankarow dot de server in karow
nuremberg mercurix at wlankarow dot de server in nürnberg
moabit mercurix at wlankarow dot de WRT54G in der Kruppstr. 13
gw-floh-1 onlinefloh dot freifunk at web dot de router @home
leipzig-l2gvpn-main freifunk wwsnet net F²x (Kopplung HauptVPN - Berlin)
jow freifunk wwsnet net F²x #2
gw-floh-2 onlinefloh dot freifunk at web dot de server @Tempelhof
schaeuble patrick lunatiki de pberg vpn gate
inorouter patrick lunatiki de xberg Zossener uplink
zeratul andreas dot pittrich web de
caminetto-2 Prometheus
23-5 freifunk@23-5.eu
chi.cyranjo.org steven midlink org Freifunk Halle VPN #1
bno_test dennis_bartsch hotmail com
hannover toxxic freifunk-hannover de Freifunk Hannover Testing
joti johannes soziologiker org Hostname ändert sich noch, update ich dann
56.3 freifunkbs gmx-topmail de Test
wien aaron dot lo-res dotdotdot org via tunnel.wien.funkfeuer.at
hamburg ds at ainex net bgp vpn router
charon.fh.ff.jpod.cc freifunk at jpod.cc fhain vpn gate0
wrt0.fh.ff.jpod.cc freifunk at jpod.cc fhain vpn gate1
houston freifunk at jpod.cc FOKUS vpn gate
vpn4.ff.jpod.cc freifunk at jpod.cc vpn gate
cronus.ff.jpod.cc freifunk at jpod.cc vpn gate
erfurt sb at ilmbeat net http://erfurt.freifunk.net
rhea.ff.jpod.cc freifunk at jpod.cc vpn gate
pberg.freifunk.net admin at pberg dot freifunk dot net http://pberg.freifunk.net
chinchilla robin pt pberg dot freifunk dot net
wonka w-l2gvpn near chaos dot in-kiel dot de test test test :)
StefanoGSoC pillastefano at gmail dot com Tunnel for GSoC Project
jwyzer1 john dot wyzer at gmx dot de lonely node in x-berg
bubble andre dot riehl at web dot de lonely node in Lichtenberg

Ipv6 addresses

uses fdca:ffee:babe:dad0::/64 - http://www.sixxs.net/tools/grh/ula/list/

OLSR config


For olsrd v4 status look at http://vpn.berlin.freifunk.net:8080/nodes

to use the tunnel, add l2gvpn interface to olsr configuration at /etc/config/olsr

config 'Interface'
        option 'Interface'        'bbb'
        option 'HelloInterval'    '10.0'
        option 'HelloValidityTime'        '900.0'
        option 'TcInterval'       '30.0'
        option 'TcValidityTime'   '2700.0'
        option 'MidInterval'      '150.0'
        option 'MidValidityTime'  '2700.0'
        option 'HnaInterval'      '150.0'
        option 'HnaValidityTime'  '900.0'
        option 'Ip4Broadcast'     ''
        option 'LinkQualityMult'  'default 0.1'
        option 'LinkQualityMult'  ' 0.5'


For olsrd v6 status look at http://vpn.berlin.freifunk.net:8080/nodes

More Info for our 6Mesh Tests at 6mesh.freifunk.net

config 'Interface'
        option 'Interface'       'bbb'
        option 'HelloInterval'    '10.0'
        option 'HelloValidityTime'        '900.0'
        option 'TcInterval'       '30.0'
        option 'TcValidityTime'   '2700.0'
        option 'MidInterval'      '150.0'
        option 'MidValidityTime'  '2700.0'
        option 'HnaInterval'      '150.0'
        option 'HnaValidityTime'  '900.0'
        option 'Ip6AddrType'      'global'
        option 'LinkQualityMult'  'default 0.1'
        option 'LinkQualityMult'  ' 0.5'

OSPF config




! Sample configuration file for vtysh.
service integrated-vtysh-config
!hostname quagga-router
username root nopassword


log file /var/log/quagga/bgpd.log
log syslog informational
password freifunk2009
enable password freifunk2009
interface bbb
 ip ospf authentication-key freifunk
 ipv6 nd suppress-ra
router ospf
 ospf router-id 77.87.48.XX
 network area
 network 77.87.<your net>/xx area
ip forwarding
ipv6 forwarding
line vty

test cases

gvpn test cases

  • ipv6
    • RA (gibs ne adresse vom benachbarten radvd)
    • neighbour rechability via ll-addr. (ndp testen) (ping6 ll-nachbar)
    • olsr (kommt multicast an? olsr nachbarn?) einheitliche olsr version
    • routing (von 1 hop hinter vpn zu 1 hop hinter vpn)
  • ipv4
    • olsr (nachbarn?)
      • std broadcast (kommt er an?)
      • full broadcast (kommt er an?)
      • link local multicast (komm er an?)
    • routing (von 1 hop hinter vpn zu 1 hop hinter vpn)
    • arp (ping ll-nachbar)
    • dhcp (dhclient)
  • layer-2
    • bridging (gehen all diese tests auch, wenn der testnode per bridge am tap device hängt?)
    • STP? (gute frage)
  • MTU
    • Path MTU discovery (ping?) (tcp?) (tools?)
linux: tracepath
  • generelly administrativia
    • syncrone revisionen (nighly builds)
      • automatische generierung von packages
        • debian (libuci statisch linken.)
        • openwrt
    • geskriptete updates, ssh keys
  • jitter messung?
  • periodische bandbreitenvergleiche zwischen mit vpn und ohne vpn (tcp)

fixes n2n_v1

set netmask via command line argument

Important.png Wichtig: Already done at no-route.org SVN repo.

Here is a more clean (kind of) solution to supply the subnet mask via command line argument:

--- edge.c	2008-12-11 16:54:00.000000000 +0100
+++ edge.c	2008-12-11 21:40:15.000000000 +0100
@@ -17,6 +17,7 @@
  * Code contributions courtesy of:
  * Richard Andrews <bbmaj7@yahoo.com.au>
  * Don Bindner <don.bindner@gmail.com>
+ * Sylwester Sosnowski <syso-n2n@no-route.org>
@@ -252,6 +253,7 @@
 	 "-a <tun IP address> "
 	 "-c <community> "
 	 "-k <encrypt key> "
+	 "-s <subnet mask> "
 #ifndef WIN32
 	 "[-u <uid> -g <gid>]"
@@ -271,6 +273,7 @@
   printf("-k <encrypt key>         | Encryption key (ASCII) - also N2N_KEY=<encrypt key>\n");
   printf("-l <supernode host:port> | Supernode IP:port\n");
   printf("-p <local port>          | Local port used for connecting to supernode\n");
+  printf("-s <subnet mask>         | n2n Subnet mask (Default:\n");
 #ifndef WIN32
   printf("-u <UID>                 | User ID (numeric) to use when privileges are dropped\n");
   printf("-g <GID>                 | Group ID (numeric) to use when privileges are dropped\n");
@@ -1125,7 +1128,9 @@
   int opt, local_port = 0 /* any port */;
   char *tuntap_dev_name = "edge0";
   char *ip_addr = NULL;
+  char *subnet_mask = "";
   ipstr_t ip_buf;
+  int got_s = 0;
 #ifndef WIN32
   uid_t userid=0; /* root is the only guaranteed ID */
@@ -1196,7 +1201,7 @@
   /* {int k;for(k=0;k<effectiveargc;++k)  printf("%s\n",effectiveargv[k]);} */
   optarg = NULL;
-  while((opt = getopt_long(effectiveargc, effectiveargv, "k:a:c:u:g:m:d:l:p:fvhrt", long_options, NULL)) != EOF) {
+  while((opt = getopt_long(effectiveargc, effectiveargv, "k:a:c:u:g:m:s:d:l:p:fvhrt", long_options, NULL)) != EOF) {
     switch (opt) {
     case 'a':
       ip_addr = strdup(optarg);
@@ -1249,6 +1254,14 @@
     case 'p':
       local_port = atoi(optarg);
+    case 's': /* Subnet Mask */
+      if (got_s == 1) {
+          traceEvent(TRACE_WARNING, "Multiple subnet masks supplied.");
+          free(subnet_mask);
+      }
+      subnet_mask = strdup(optarg);
+      got_s = 1;
+      break;
     case 'h': /* help */
@@ -1274,7 +1287,7 @@
   /* setgid( 0 ); */
-  if(tuntap_open(&(eee.device), tuntap_dev_name, ip_addr, "", device_mac ) < 0)
+  if(tuntap_open(&(eee.device), tuntap_dev_name, ip_addr, subnet_mask, device_mac ) < 0)
 #ifndef WIN32

allow broadcast packets to every address, modify the packet_check to allow all packets


to allow broadcast packets to every address (i.e. OLSR bcast modify the packet_check to allow all packets.

Index: edge.c
--- edge.c      (revision 3626)
+++ edge.c      (working copy)
@@ -865,6 +865,10 @@
          traceEvent(TRACE_INFO, "Discarding routed packet [rcvd=%s][expected=%s]",
                     intoa(ntohl(the_ip->ip_dst.s_addr), ip_buf, sizeof(ip_buf)),
                     intoa(ntohl(eee->device.ip_addr), ip_buf2, sizeof(ip_buf2)));
+       /* dpa */
+       return(0);
        } else {
        /* This packet is for us */

less ugly (by wonka)

Index: edge.c
--- edge.c	(revision 3593)
+++ edge.c	(working copy)
@@ -725,9 +725,12 @@
       /* Note: all elements of the_ip are in network order */
       struct ip *the_ip = (struct ip*)(pkt+sizeof(struct ether_header));
+      struct in_addr bcast = { 0xffffffff };
       if((the_ip->ip_dst.s_addr != eee->device.ip_addr)
-	 && ((the_ip->ip_dst.s_addr & eee->device.device_mask) != (eee->device.ip_addr & eee->device.device_mask))) /* Not a broadcast */
+	 && ((the_ip->ip_dst.s_addr & eee->device.device_mask) != (eee->device.ip_addr & eee->device.device_mask)) /* Not a broadcast */
+	 && ((the_ip->ip_dst.s_addr) != (bcast.s_addr))) /* really not a broadcast */
           ipstr_t ip_buf;
           ipstr_t ip_buf2;

see also