Add the Forwarding option.
authorGuus Sliepen <guus@tinc-vpn.org>
Tue, 2 Mar 2010 21:34:26 +0000 (22:34 +0100)
committerGuus Sliepen <guus@tinc-vpn.org>
Tue, 2 Mar 2010 21:34:26 +0000 (22:34 +0100)
This determines if and how incoming packets that are not meant for the local
node are forwarded.  It can either be off, internal (tinc forwards them itself,
as in previous versions), or kernel (packets are always sent to the TUN/TAP
device, letting the kernel sort them out).

doc/tinc.conf.5.in
doc/tinc.texi
src/net_setup.c
src/route.c
src/route.h

index 6f8db9c..797ca52 100644 (file)
@@ -199,6 +199,26 @@ Tinc will expect packets read from the virtual network device
 to start with an Ethernet header.
 .El
 
 to start with an Ethernet header.
 .El
 
+.It Va Forwarding Li = off | internal | kernel Pq internal
+This option selects the way indirect packets are forwarded.
+.Bl -tag -width indent
+
+.It off
+Incoming packets that are not meant for the local node,
+but which should be forwarded to another node, are dropped.
+
+.It internal
+Incoming packets that are meant for another node are forwarded by tinc internally.
+
+.Pp
+This is the default mode, and unless you really know you need another forwarding mode, don't change it.
+
+.It kernel
+Incoming packets are always sent to the TUN/TAP device, even if the packets are not for the local node.
+This is less efficient, but allows the kernel to apply its routing and firewall rules on them,
+and can also help debugging.
+.El
+
 .It Va GraphDumpFile Li = Ar filename Bq experimental
 If this option is present,
 .Nm tinc
 .It Va GraphDumpFile Li = Ar filename Bq experimental
 If this option is present,
 .Nm tinc
index 5d0bf31..091b5e7 100644 (file)
@@ -818,6 +818,26 @@ Tinc will expect packets read from the virtual network device
 to start with an Ethernet header.
 @end table
 
 to start with an Ethernet header.
 @end table
 
+@cindex Forwarding
+@item Forwarding = <off|internal|kernel> (internal)
+This option selects the way indirect packets are forwarded.
+
+@table @asis
+@item off
+Incoming packets that are not meant for the local node,
+but which should be forwarded to another node, are dropped.
+
+@item internal
+Incoming packets that are meant for another node are forwarded by tinc internally.
+
+This is the default mode, and unless you really know you need another forwarding mode, don't change it.
+
+@item kernel
+Incoming packets are always sent to the TUN/TAP device, even if the packets are not for the local node.
+This is less efficient, but allows the kernel to apply its routing and firewall rules on them,
+and can also help debugging.
+@end table
+
 @cindex GraphDumpFile
 @item GraphDumpFile = <@var{filename}> [experimental]
 If this option is present,
 @cindex GraphDumpFile
 @item GraphDumpFile = <@var{filename}> [experimental]
 If this option is present,
index cb606ca..6e51b2e 100644 (file)
@@ -355,8 +355,21 @@ bool setup_myself(void) {
                        return false;
                }
                free(mode);
                        return false;
                }
                free(mode);
-       } else
-               routing_mode = RMODE_ROUTER;
+       }
+
+       if(get_config_string(lookup_config(config_tree, "Forwarding"), &mode)) {
+               if(!strcasecmp(mode, "off"))
+                       routing_mode = FMODE_OFF;
+               else if(!strcasecmp(mode, "internal"))
+                       routing_mode = FMODE_INTERNAL;
+               else if(!strcasecmp(mode, "kernel"))
+                       routing_mode = FMODE_KERNEL;
+               else {
+                       logger(LOG_ERR, "Invalid forwarding mode!");
+                       return false;
+               }
+               free(mode);
+       }
 
        choice = true;
        get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice);
 
        choice = true;
        get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice);
index 6c381cc..1f91db9 100644 (file)
@@ -33,6 +33,7 @@
 #include "utils.h"
 
 rmode_t routing_mode = RMODE_ROUTER;
 #include "utils.h"
 
 rmode_t routing_mode = RMODE_ROUTER;
+fmode_t forwarding_mode = FMODE_INTERNAL;
 bool priorityinheritance = false;
 int macexpire = 600;
 bool overwrite_mac = false;
 bool priorityinheritance = false;
 int macexpire = 600;
 bool overwrite_mac = false;
@@ -383,7 +384,10 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) {
        }
 
        if(!subnet->owner->status.reachable)
        }
 
        if(!subnet->owner->status.reachable)
-               route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_UNREACH);
+               return route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_UNREACH);
+
+       if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself)
+               return route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_ANO);
 
        if(priorityinheritance)
                packet->priority = packet->data[15];
 
        if(priorityinheritance)
                packet->priority = packet->data[15];
@@ -531,7 +535,10 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) {
        }
 
        if(!subnet->owner->status.reachable)
        }
 
        if(!subnet->owner->status.reachable)
-               route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE);
+               return route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE);
+
+       if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself)
+               return route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN);
 
        via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via;
        
 
        via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via;
        
@@ -796,6 +803,9 @@ static void route_mac(node_t *source, vpn_packet_t *packet) {
                return;
        }
 
                return;
        }
 
+       if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself)
+               return;
+
        // Handle packets larger than PMTU
 
        node_t *via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via;
        // Handle packets larger than PMTU
 
        node_t *via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via;
@@ -824,6 +834,11 @@ static void route_mac(node_t *source, vpn_packet_t *packet) {
 }
 
 void route(node_t *source, vpn_packet_t *packet) {
 }
 
 void route(node_t *source, vpn_packet_t *packet) {
+       if(forwarding_mode == FMODE_KERNEL) {
+               send_packet(myself, packet);
+               return;
+       }
+
        if(!checklength(source, packet, ether_size))
                return;
 
        if(!checklength(source, packet, ether_size))
                return;
 
index 1fcc6be..aa25dcf 100644 (file)
@@ -30,7 +30,14 @@ typedef enum rmode_t {
        RMODE_ROUTER,
 } rmode_t;
 
        RMODE_ROUTER,
 } rmode_t;
 
+typedef enum fmode_t {
+       FMODE_OFF = 0,
+       FMODE_INTERNAL,
+       FMODE_KERNEL,
+} fmode_t;
+
 extern rmode_t routing_mode;
 extern rmode_t routing_mode;
+extern fmode_t forwarding_mode;
 extern bool overwrite_mac;
 extern bool priorityinheritance;
 extern int macexpire;
 extern bool overwrite_mac;
 extern bool priorityinheritance;
 extern int macexpire;