Hi everybody,

I am part of the LEAF project - a small distro for embedded environments - at http://leaf.sourceforge.net (I'm actually only part of the "Bering uClibc" branch, to be precise).

Since LEAF does not provide ifconfig and route by default (just iproute2) I created a patch that allows using OpenVPN on LEAF boxes without the need for ifconfig and route.

I would be very happy to see this integrated into OpenVPN at some point (there's no hurry - we have a mostly automated build environment, so applying the patch is no big deal).

I've tested the patch using a LEAF box plus a regular Fedora box (both tun and tap devices) and everything seems to be working nicely.

If the patch doesn't make it onto the list (the LEAF lists trim all attachments), it can also be found at:
http://cvs.sourceforge.net/viewcvs.py/leaf/src/bering-uclibc/apps/openvpn/iproute.patch

Let me know if you have any questions.

Martin
diff -N -u -r -b openvpn-1.6_beta1/misc.c openvpn-1.6_beta1.hejl/misc.c
--- openvpn-1.6_beta1/misc.c    Wed Jan 14 07:54:34 2004
+++ openvpn-1.6_beta1.new/misc.c        Thu Jan 15 11:33:07 2004
@@ -680,3 +680,29 @@
       ++cp;
     }
 }
+
+
+/*
+ * 'stolen' from busybox networking/ifupdown.c
+ */
+unsigned int count_bits(unsigned int a)
+{
+       unsigned int result;
+       result = (a & 0x55) + ((a >> 1) & 0x55);
+       result = (result & 0x33) + ((result >> 2) & 0x33);
+       return((result & 0x0F) + ((result >> 4) & 0x0F));
+}
+
+int count_netmask_bits(const char *dotted_quad)
+{
+       unsigned int result, a, b, c, d;
+       /* Found a netmask...  Check if it is dotted quad */
+       if (sscanf(dotted_quad, "%u.%u.%u.%u", &a, &b, &c, &d) != 4)
+               return -1;
+       result = count_bits(a);
+       result += count_bits(b);
+       result += count_bits(c);
+       result += count_bits(d);
+       return ((int)result);
+}
+
diff -N -u -r -b openvpn-1.6_beta1/misc.h openvpn-1.6_beta1.hejl/misc.h
--- openvpn-1.6_beta1/misc.h    Thu Nov  6 14:45:12 2003
+++ openvpn-1.6_beta1.hejl/misc.h       Thu Jan 15 09:38:32 2004
@@ -138,6 +139,10 @@
 void setenv_int (const char *name, int value);
 void setenv_del (const char *name);

+/* convert netmasks for iproute2 */
+int count_netmask_bits(const char *);
+unsigned int count_bits(unsigned int );
+
 /* make cp safe to be passed to system() or set as an environmental variable */
 void safe_string (char *cp);

@@ -171,3 +176,4 @@
 }

 #endif
+
diff -N -u -r -b openvpn-1.6_beta1/route.c openvpn-1.6_beta1.hejl/route.c
--- openvpn-1.6_beta1/route.c   Thu Nov  6 14:45:12 2003
+++ openvpn-1.6_beta1.hejl/route.c      Thu Jan 15 09:32:30 2004
@@ -525,6 +525,7 @@
     setenv_route (&rl->routes[i], i + 1);
 }

+
 static void
 add_route (struct route *r)
 {
@@ -545,14 +546,22 @@
   gateway = print_in_addr_t (r->gateway, false);

 #if defined(TARGET_LINUX)
+#ifdef CONFIG_FEATURE_IPROUTE
+  buf_printf (&buf, IPROUTE_PATH " route add %s/%d via %s",
+             network,
+             count_netmask_bits(netmask),
+             gateway);
+  if (r->metric_defined)
+    buf_printf (&buf, " metric %d", r->metric);

+#else
   buf_printf (&buf, ROUTE_PATH " add -net %s netmask %s gw %s",
              network,
              netmask,
              gateway);
   if (r->metric_defined)
     buf_printf (&buf, " metric %d", r->metric);
-
+#endif  /*CONFIG_FEATURE_IPROUTE*/
   msg (D_ROUTE, "%s", BSTR (&buf));
   status = system_check (BSTR (&buf), "ERROR: Linux route add command failed", 
false);

@@ -650,11 +659,16 @@
   gateway = print_in_addr_t (r->gateway, false);

 #if defined(TARGET_LINUX)
+#ifdef CONFIG_FEATURE_IPROUTE
+  buf_printf (&buf, IPROUTE_PATH " route del %s/%d",
+             network,
+             count_netmask_bits(netmask));
+#else

   buf_printf (&buf, ROUTE_PATH " del -net %s netmask %s",
              network,
              netmask);
-
+#endif /*CONFIG_FEATURE_IPROUTE*/
   msg (D_ROUTE, "%s", BSTR (&buf));
   system_check (BSTR (&buf), "ERROR: Linux route delete command failed", 
false);

diff -N -u -r -b openvpn-1.6_beta1/tun.c openvpn-1.6_beta1.hejl/tun.c
--- openvpn-1.6_beta1/tun.c     Thu Nov  6 14:45:12 2003
+++ openvpn-1.6_beta1.hejl/tun.c        Thu Jan 15 09:52:58 2004
@@ -451,7 +451,46 @@
        ifconfig_broadcast = print_in_addr_t (tt->broadcast, false);

 #if defined(TARGET_LINUX)
+#ifdef CONFIG_FEATURE_IPROUTE
+       /*
+        * Set the MTU for the device
+        */
+       openvpn_snprintf (command_line, sizeof (command_line),
+                         IPROUTE_PATH " link set dev %s up mtu %d",
+                         actual,
+                         tun_mtu
+                         );
+         msg (M_INFO, "%s", command_line);
+         system_check (command_line, "Linux ip link set failed", true);

+
+       if (tun) {
+
+               /*
+                * Set the address for the device
+                */
+               openvpn_snprintf (command_line, sizeof (command_line),
+                                 IPROUTE_PATH " addr add dev %s local %s peer 
%s",
+                                 actual,
+                                 ifconfig_local,
+                                 ifconfig_remote_netmask
+                                 );
+                 msg (M_INFO, "%s", command_line);
+                 system_check (command_line, "Linux ip addr add failed", true);
+       } else {
+               openvpn_snprintf (command_line, sizeof (command_line),
+                                 IPROUTE_PATH " addr add dev %s %s/%d 
broadcast %s",
+                                 actual,
+                                 ifconfig_local,
+                                 count_netmask_bits(ifconfig_remote_netmask),
+                                 ifconfig_broadcast
+                                 );
+                 msg (M_INFO, "%s", command_line);
+                 system_check (command_line, "Linux ip addr add failed", true);
+
+       }
+       tt->did_ifconfig = true;
+#else
       if (tun)
        openvpn_snprintf (command_line, sizeof (command_line),
                          IFCONFIG_PATH " %s %s pointopoint %s mtu %d",
@@ -472,7 +511,7 @@
       msg (M_INFO, "%s", command_line);
       system_check (command_line, "Linux ifconfig failed", true);
       tt->did_ifconfig = true;
-
+#endif /*CONFIG_FEATURE_IPROUTE*/
 #elif defined(TARGET_SOLARIS)

       /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 
255.255.255.255 up */
--- openvpn-1.6_beta1/configure.ac      Wed Jan 14 21:30:21 2004
+++ openvpn-1.6_beta1.new/configure.ac  Thu Jan 15 11:33:43 2004
@@ -106,6 +106,14 @@
 )
 AC_DEFINE_UNQUOTED(IFCONFIG_PATH, "$IFCONFIG", [Path to ifconfig tool])

+AC_ARG_WITH(iproute-path,
+   [  --with-iproute-path=PATH    Path to iproute tool],
+   [IPROUTE="$withval"],
+   [AC_PATH_PROG([IPROUTE], [ip], [ip], 
[$PATH:/usr/local/sbin:/usr/sbin:/sbin])]
+)
+AC_DEFINE_UNQUOTED(IPROUTE_PATH, "$IPROUTE", [Path to iproute tool])
+
+
 AC_ARG_WITH(route-path,
    [  --with-route-path=PATH  Path to route tool],
    [ROUTE="$withval"],
@@ -118,6 +126,13 @@
    [LEAK="$withval"]
 )

+AC_ARG_ENABLE(iproute2,
+   [  --enable-iproute2       Enable support for iproute2],
+   AC_DEFINE(CONFIG_FEATURE_IPROUTE, 1, [enable iproute2 support])
+   
+)
+
+
 dnl Guess host type.
 AC_CANONICAL_HOST
 AC_CANONICAL_SYSTEM

Reply via email to