sysctl: fix compatibility with procps sysctl
Busybox sysctl is incompatible with procps when '.' appears in
directory name, mostly happens with VLANs.
busybox syntax (since 2008): net.ipv4.conf.eth0.100.mc_forwarding
procps syntax (since 2002): net.ipv4.conf.eth0/100.mc_forwarding
(supported by both: net/ipv4/conf/eth0.100/mc_forwarding)
Use procps syntax for output; for input, allow both.
function old new delta
sysctl_dots_to_slashes 86 143 +57
sysctl_act_on_setting 443 453 +10
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 67/0) Total: 67 bytes
Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
diff --git a/procps/sysctl.c b/procps/sysctl.c
index 5303460..6d77185 100644
--- a/procps/sysctl.c
+++ b/procps/sysctl.c
@@ -56,9 +56,32 @@
static void sysctl_dots_to_slashes(char *name)
{
- char *cptr, *last_good, *end;
+ char *cptr, *last_good, *end, *slash;
char end_ch;
+ end = strchrnul(name, '=');
+
+ slash = strchrnul(name, '/');
+ if (slash < end
+ && strchrnul(name, '.') < slash
+ ) {
+ /* There are both dots and slashes, and 1st dot is
+ * before 1st slash.
+ * (IOW: not raw, unmangled a/b/c.d format)
+ *
+ * procps supports this syntax for names with dots:
+ * net.ipv4.conf.eth0/100.mc_forwarding
+ * (dots and slashes are simply swapped)
+ */
+ while (end != name) {
+ end--;
+ if (*end == '.') *end = '/';
+ else if (*end == '/') *end = '.';
+ }
+ return;
+ }
+ /* else: use our old behavior: */
+
/* Convert minimum number of '.' to '/' so that
* we end up with existing file's name.
*
@@ -77,7 +100,6 @@
*
* To set up testing: modprobe 8021q; vconfig add eth0 100
*/
- end = strchrnul(name, '=');
end_ch = *end;
*end = '.'; /* trick the loop into trying full name too */
@@ -114,6 +136,8 @@
while (*cptr) {
if (*cptr == '/')
*cptr = '.';
+ else if (*cptr == '.')
+ *cptr = '/';
cptr++;
}