From 1f6f67aa36402efd53fab5efd2124ace6396e8aa Mon Sep 17 00:00:00 2001
From: Julien Muchembled <jm@nexedi.com>
Date: Mon, 10 Sep 2012 16:40:08 +0200
Subject: [PATCH] Simplify by setting re6st IP on loopback interface by default

---
 re6st/ovpn-server | 35 ++++++++++-------------------------
 re6st/plib.py     |  4 ++--
 re6st/tunnel.py   |  1 -
 re6stnet          | 31 ++++++++++++++-----------------
 4 files changed, 26 insertions(+), 45 deletions(-)

diff --git a/re6st/ovpn-server b/re6st/ovpn-server
index 48ad3ac..02b521b 100755
--- a/re6st/ovpn-server
+++ b/re6st/ovpn-server
@@ -1,28 +1,13 @@
 #!/usr/bin/python -S
-import os
-import sys
+import os, sys
 
-script_type = os.environ['script_type']
-arg1 = sys.argv[1]
-
-if script_type == 'up':
-    import subprocess
-    def call(*args):
-        r = subprocess.call(args)
-        if r:
-            sys.exit(r)
-    dev = os.environ['dev']
-    call('ip', 'link', 'set', dev, 'up')
-    if arg1 != 'None':
-        call('ip', 'addr', 'add', arg1, 'dev', dev)
+if os.environ['script_type'] == 'client-connect':
+    # Send client its external ip address
+    with open(sys.argv[2], 'w') as f:
+        f.write('push "setenv-safe external_ip %s"\n'
+                % os.environ['trusted_ip'])
 
-else:
-    if script_type == 'client-connect':
-        # Send client its external ip address
-        with open(sys.argv[2], 'w') as f:
-            f.write('push "setenv-safe external_ip %s"\n'
-                    % os.environ['trusted_ip'])
-
-    # Write into pipe connect/disconnect events
-    if arg1 != 'None':
-        os.write(int(arg1), '%(script_type)s %(common_name)s\n' % os.environ)
+# Write into pipe connect/disconnect events
+arg1 = sys.argv[1]
+if arg1 != 'None':
+    os.write(int(arg1), '%(script_type)s %(common_name)s\n' % os.environ)
diff --git a/re6st/plib.py b/re6st/plib.py
index 203fc9e..c0f2f64 100644
--- a/re6st/plib.py
+++ b/re6st/plib.py
@@ -13,6 +13,7 @@ def openvpn(iface, encrypt, *args, **kw):
         '--persist-tun',
         '--persist-key',
         '--script-security', '2',
+        '--up', ovpn_client,
         #'--user', 'nobody', '--group', 'nogroup',
         ] + list(args)
     if ovpn_log:
@@ -23,14 +24,13 @@ def openvpn(iface, encrypt, *args, **kw):
     return subprocess.Popen(args, **kw)
 
 
-def server(iface, my_ip, max_clients, dh_path, pipe_fd, port, proto, encrypt, *args, **kw):
+def server(iface, max_clients, dh_path, pipe_fd, port, proto, encrypt, *args, **kw):
     client_script = '%s %s' % (ovpn_server, pipe_fd)
     if pipe_fd is not None:
         args = ('--client-disconnect', client_script) + args
     return openvpn(iface, encrypt,
         '--tls-server',
         '--mode', 'server',
-        '--up', '%s %s' % (ovpn_server, my_ip),
         '--client-connect', client_script,
         '--dh', dh_path,
         '--max-clients', str(max_clients),
diff --git a/re6st/tunnel.py b/re6st/tunnel.py
index c5388c2..2847110 100644
--- a/re6st/tunnel.py
+++ b/re6st/tunnel.py
@@ -15,7 +15,6 @@ class Connection:
             '--tls-remote', '%u/%u' % (int(prefix, 2), len(prefix)),
             '--connect-retry-max', '3', '--tls-exit',
             '--ping-exit', str(timeout),
-            '--up', plib.ovpn_client,
             '--route-up', '%s %u' % (plib.ovpn_client, write_pipe),
             *ovpn_args)
         self.iface = iface
diff --git a/re6stnet b/re6stnet
index cbaa96c..c1250a6 100755
--- a/re6stnet
+++ b/re6stnet
@@ -32,9 +32,9 @@ def getConfig():
     _('-i', '--interface', action='append', dest='iface_list', default=[],
         help="Extra interface for LAN discovery. Highly recommanded if there"
              " are other re6st node on the same network segment.")
-    _('-I', '--main-interface', metavar='IFACE',
+    _('-I', '--main-interface', metavar='IFACE', default='lo',
         help="Set re6stnet IP on given interface. Any interface not used for"
-             " tunnelling can be chosen. (default: first OpenVPN interface)")
+             " tunnelling can be chosen.")
 
     _ = parser.add_argument_group('routing').add_argument
     _('-B', dest='babel_args', metavar='ARG', action='append', default=[],
@@ -205,27 +205,24 @@ def main():
             # prepare persistent interfaces
             if config.client:
                 cleanup.append(plib.client('re6stnet', config.client,
-                    config.encrypt,
-                    '--up', '%s %s' % (plib.ovpn_server, None
-                        if config.main_interface else my_ip),
-                    '--ping-restart', str(timeout),
+                    config.encrypt, '--ping-restart', str(timeout),
                     *config.openvpn_args).kill)
             elif server_tunnels:
                 required('dh')
                 for iface, (port, proto) in server_tunnels.iteritems():
-                    cleanup.append(plib.server(iface, None
-                        if config.main_interface or proto != pp[0][1]
-                        else my_ip, config.max_clients, config.dh, write_pipe,
-                        port, proto, config.encrypt,
+                    cleanup.append(plib.server(iface, config.max_clients,
+                        config.dh, write_pipe, port, proto, config.encrypt,
                         '--ping-exit', str(timeout), *config.openvpn_args).kill)
-            elif config.iface_list and not config.main_interface:
-                config.main_interface = config.iface_list[0]
-            else:
-                sys.exit("--client, --interface or --main-interface required"
-                         " when --max-clients is 0")
 
-            if config.main_interface:
-                ip('addr', my_ip, 'dev', config.main_interface)
+            ip('addr', my_ip, 'dev', config.main_interface)
+            if config.main_interface == 'lo':
+                # WKRD: The kernel does not remove these routes on exit.
+                #       The first one can be removed now.
+                del_rtr = ['ip', 'route', 'del', 'unreachable', 'fe80::/64',
+                           'dev', 'lo']
+                subprocess.call(del_rtr)
+                del_rtr[4] = '%s/%u' % (utils.ipFromBin(subnet), len(subnet))
+                cleanup.append(lambda: subprocess.call(del_rtr))
 
             # main loop
             if tunnel_manager is None:
-- 
2.30.9