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.cWed Jan 14 07:54:34 2004
+++ openvpn-1.6_beta1.new/misc.cThu 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.hThu 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.cThu 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),
+