[Babel-users] [PATCH v4 1/2] Rework sysctl writing to only write when needed.

Toke Høiland-Jørgensen toke at toke.dk
Thu Aug 20 09:29:29 UTC 2015


This reworks the sysctl handling to only write a sysctl if it is not
already the desired value. In addition, the Linux sysctl knobs are now
stored in a lookup table which is looped through, to avoid code
duplication in the setup routine.

Signed-off-by: Toke Høiland-Jørgensen <toke at toke.dk>
---
 kernel_netlink.c | 131 +++++++++++++++++--------------------------------------
 kernel_socket.c  |  23 ++++++----
 2 files changed, 56 insertions(+), 98 deletions(-)

diff --git a/kernel_netlink.c b/kernel_netlink.c
index ab63d33..557f7fa 100644
--- a/kernel_netlink.c
+++ b/kernel_netlink.c
@@ -58,10 +58,19 @@ THE SOFTWARE.
 
 int export_table = -1, import_tables[MAX_IMPORT_TABLES], import_table_count = 0;
 
-static int old_forwarding = -1;
-static int old_ipv4_forwarding = -1;
-static int old_accept_redirects = -1;
-static int old_rp_filter = -1;
+struct sysctl_setting {
+    char *name;
+    int want;
+    int was;
+};
+#define NUM_SYSCTLS 4
+
+static struct sysctl_setting sysctl_settings[NUM_SYSCTLS] = {
+    {"/proc/sys/net/ipv6/conf/all/forwarding", 1, -1},
+    {"/proc/sys/net/ipv4/conf/all/forwarding", 1, -1},
+    {"/proc/sys/net/ipv6/conf/all/accept_redirects", 0, -1},
+    {"/proc/sys/net/ipv4/conf/all/rp_filter", 0, -1},
+};
 
 struct old_if {
     char *ifname;
@@ -480,10 +489,12 @@ netlink_send_dump(int type, void *data, int len) {
     return 0;
 }
 
+
 int
 kernel_setup(int setup)
 {
-    int rc;
+    struct sysctl_setting *s;
+    int i, rc;
 
     if(setup) {
         if(export_table < 0)
@@ -503,56 +514,21 @@ kernel_setup(int setup)
         }
         nl_setup = 1;
 
-        old_forwarding = read_proc("/proc/sys/net/ipv6/conf/all/forwarding");
-        if(old_forwarding < 0) {
-            perror("Couldn't read forwarding knob.");
-            return -1;
-        }
-
-        rc = write_proc("/proc/sys/net/ipv6/conf/all/forwarding", 1);
-        if(rc < 0) {
-            perror("Couldn't write forwarding knob.");
-            return -1;
-        }
-
-        old_ipv4_forwarding =
-            read_proc("/proc/sys/net/ipv4/conf/all/forwarding");
-        if(old_ipv4_forwarding < 0) {
-            perror("Couldn't read IPv4 forwarding knob.");
-            return -1;
-        }
 
-        rc = write_proc("/proc/sys/net/ipv4/conf/all/forwarding", 1);
-        if(rc < 0) {
-            perror("Couldn't write IPv4 forwarding knob.");
-            return -1;
-        }
-
-
-        old_accept_redirects =
-            read_proc("/proc/sys/net/ipv6/conf/all/accept_redirects");
-        if(old_accept_redirects < 0) {
-            perror("Couldn't read accept_redirects knob.");
-            return -1;
-        }
-
-        rc = write_proc("/proc/sys/net/ipv6/conf/all/accept_redirects", 0);
-        if(rc < 0) {
-            perror("Couldn't write accept_redirects knob.");
-            return -1;
-        }
-
-        old_rp_filter =
-            read_proc("/proc/sys/net/ipv4/conf/all/rp_filter");
-        if(old_rp_filter < 0) {
-            perror("Couldn't read rp_filter knob.");
-            return -1;
-        }
-
-        rc = write_proc("/proc/sys/net/ipv4/conf/all/rp_filter", 0);
-        if(rc < 0) {
-            perror("Couldn't write rp_filter knob.");
-            return -1;
+        for(i=0; i<NUM_SYSCTLS; i++) {
+            s = &sysctl_settings[i];
+            s->was = read_proc(s->name);
+            if(s->was < 0) {
+                perror("Couldn't read sysctl");
+                return -1;
+            }
+            if(s->was != s->want) {
+                rc = write_proc(s->name, s->want);
+                if(rc < 0) {
+                    perror("Couldn't write sysctl");
+                    return -1;
+                }
+            }
         }
 
         return 1;
@@ -561,46 +537,21 @@ kernel_setup(int setup)
         close(dgram_socket);
         dgram_socket = -1;
 
-        if(old_forwarding >= 0) {
-            rc = write_proc("/proc/sys/net/ipv6/conf/all/forwarding",
-                            old_forwarding);
-            if(rc < 0) {
-                perror("Couldn't write forwarding knob.\n");
-                return -1;
-            }
-        }
-
-        if(old_ipv4_forwarding >= 0) {
-            rc = write_proc("/proc/sys/net/ipv4/conf/all/forwarding",
-                            old_ipv4_forwarding);
-            if(rc < 0) {
-                perror("Couldn't write IPv4 forwarding knob.\n");
-                return -1;
-            }
-        }
-
-        if(old_accept_redirects >= 0) {
-            rc = write_proc("/proc/sys/net/ipv6/conf/all/accept_redirects",
-                            old_accept_redirects);
-            if(rc < 0) {
-                perror("Couldn't write accept_redirects knob.\n");
-                return -1;
-            }
-        }
+        close(nl_command.sock);
+        nl_command.sock = -1;
+        nl_setup = 0;
 
-        if(old_rp_filter >= 0) {
-            rc = write_proc("/proc/sys/net/ipv4/conf/all/rp_filter",
-                            old_rp_filter);
-            if(rc < 0) {
-                perror("Couldn't write rp_filter knob.\n");
-                return -1;
+        for(i=0; i<NUM_SYSCTLS; i++) {
+            s = &sysctl_settings[i];
+            if(s->was && s->was != s->want) {
+                rc = write_proc(s->name,s->was);
+                if(rc < 0) {
+                    perror("Couldn't write sysctl");
+                    return -1;
+                }
             }
         }
 
-        close(nl_command.sock);
-        nl_command.sock = -1;
-
-        nl_setup = 0;
         return 1;
 
     }
diff --git a/kernel_socket.c b/kernel_socket.c
index 739a599..24658d3 100644
--- a/kernel_socket.c
+++ b/kernel_socket.c
@@ -221,10 +221,14 @@ kernel_setup(int setup)
     mib[2] = IPPROTO_IPV6;
     mib[3] = IPV6CTL_FORWARDING;
     datasize = sizeof(old_forwarding);
-    if(setup)
-        rc = sysctl(mib, 4, &old_forwarding, &datasize,
-                    &forwarding, datasize);
-    else if(old_forwarding >= 0)
+    if(setup) {
+        rc = sysctl(mib, 4, &old_forwarding, &datasize, NULL, 0);
+        if(rc == 0 && old_forwarding != forwarding) {
+            rc = sysctl(mib, 4, &old_forwarding, &datasize,
+                        &forwarding, datasize);
+        }
+    }
+    else if(old_forwarding >= 0 && old_forwarding != forwarding)
         rc = sysctl(mib, 4, NULL, NULL,
                     &old_forwarding, datasize);
     if(rc == -1) {
@@ -240,10 +244,13 @@ kernel_setup(int setup)
     mib[3] = ICMPV6CTL_REDIRACCEPT;
 #endif
     datasize = sizeof(old_accept_redirects);
-    if(setup)
-        rc = sysctl(mib, 4, &old_accept_redirects, &datasize,
-                    &accept_redirects, datasize);
-    else if(old_accept_redirects >= 0)
+    if(setup) {
+        rc = sysctl(mib, 4, &old_accept_redirects, &datasize, NULL, 0);
+        if(rc == 0 && old_accept_redirects != accept_redirects) {
+            rc = sysctl(mib, 4, &old_accept_redirects, &datasize,
+                        &accept_redirects, datasize);
+        }
+    else if(old_accept_redirects >= 0 && old_accept_redirects != accept_redirects)
         rc = sysctl(mib, 4, NULL, NULL,
                     &old_accept_redirects, datasize);
     if(rc == -1) {
-- 
2.5.0



More information about the Babel-users mailing list