Commit 67984ffa authored by Toke Høiland-Jørgensen's avatar Toke Høiland-Jørgensen Committed by Juliusz Chroboczek

Rework sysctl writing to only write when needed.

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: default avatarToke Høiland-Jørgensen <toke@toke.dk>
parent fcc62422
...@@ -58,10 +58,19 @@ THE SOFTWARE. ...@@ -58,10 +58,19 @@ THE SOFTWARE.
int export_table = -1, import_tables[MAX_IMPORT_TABLES], import_table_count = 0; int export_table = -1, import_tables[MAX_IMPORT_TABLES], import_table_count = 0;
static int old_forwarding = -1; struct sysctl_setting {
static int old_ipv4_forwarding = -1; char *name;
static int old_accept_redirects = -1; int want;
static int old_rp_filter = -1; 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 { struct old_if {
char *ifname; char *ifname;
...@@ -480,10 +489,12 @@ netlink_send_dump(int type, void *data, int len) { ...@@ -480,10 +489,12 @@ netlink_send_dump(int type, void *data, int len) {
return 0; return 0;
} }
int int
kernel_setup(int setup) kernel_setup(int setup)
{ {
int rc; struct sysctl_setting *s;
int i, rc;
if(setup) { if(setup) {
if(export_table < 0) if(export_table < 0)
...@@ -503,56 +514,21 @@ kernel_setup(int setup) ...@@ -503,56 +514,21 @@ kernel_setup(int setup)
} }
nl_setup = 1; 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); for(i=0; i<NUM_SYSCTLS; i++) {
if(rc < 0) { s = &sysctl_settings[i];
perror("Couldn't write IPv4 forwarding knob."); s->was = read_proc(s->name);
return -1; if(s->was < 0) {
} perror("Couldn't read sysctl");
return -1;
}
old_accept_redirects = if(s->was != s->want) {
read_proc("/proc/sys/net/ipv6/conf/all/accept_redirects"); rc = write_proc(s->name, s->want);
if(old_accept_redirects < 0) { if(rc < 0) {
perror("Couldn't read accept_redirects knob."); perror("Couldn't write sysctl");
return -1; 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;
} }
return 1; return 1;
...@@ -561,46 +537,21 @@ kernel_setup(int setup) ...@@ -561,46 +537,21 @@ kernel_setup(int setup)
close(dgram_socket); close(dgram_socket);
dgram_socket = -1; dgram_socket = -1;
if(old_forwarding >= 0) { close(nl_command.sock);
rc = write_proc("/proc/sys/net/ipv6/conf/all/forwarding", nl_command.sock = -1;
old_forwarding); nl_setup = 0;
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;
}
}
if(old_rp_filter >= 0) { for(i=0; i<NUM_SYSCTLS; i++) {
rc = write_proc("/proc/sys/net/ipv4/conf/all/rp_filter", s = &sysctl_settings[i];
old_rp_filter); if(s->was && s->was != s->want) {
if(rc < 0) { rc = write_proc(s->name,s->was);
perror("Couldn't write rp_filter knob.\n"); if(rc < 0) {
return -1; perror("Couldn't write sysctl");
return -1;
}
} }
} }
close(nl_command.sock);
nl_command.sock = -1;
nl_setup = 0;
return 1; return 1;
} }
......
...@@ -221,10 +221,14 @@ kernel_setup(int setup) ...@@ -221,10 +221,14 @@ kernel_setup(int setup)
mib[2] = IPPROTO_IPV6; mib[2] = IPPROTO_IPV6;
mib[3] = IPV6CTL_FORWARDING; mib[3] = IPV6CTL_FORWARDING;
datasize = sizeof(old_forwarding); datasize = sizeof(old_forwarding);
if(setup) if(setup) {
rc = sysctl(mib, 4, &old_forwarding, &datasize, rc = sysctl(mib, 4, &old_forwarding, &datasize, NULL, 0);
&forwarding, datasize); if(rc == 0 && old_forwarding != forwarding) {
else if(old_forwarding >= 0) rc = sysctl(mib, 4, &old_forwarding, &datasize,
&forwarding, datasize);
}
}
else if(old_forwarding >= 0 && old_forwarding != forwarding)
rc = sysctl(mib, 4, NULL, NULL, rc = sysctl(mib, 4, NULL, NULL,
&old_forwarding, datasize); &old_forwarding, datasize);
if(rc == -1) { if(rc == -1) {
...@@ -240,10 +244,13 @@ kernel_setup(int setup) ...@@ -240,10 +244,13 @@ kernel_setup(int setup)
mib[3] = ICMPV6CTL_REDIRACCEPT; mib[3] = ICMPV6CTL_REDIRACCEPT;
#endif #endif
datasize = sizeof(old_accept_redirects); datasize = sizeof(old_accept_redirects);
if(setup) if(setup) {
rc = sysctl(mib, 4, &old_accept_redirects, &datasize, rc = sysctl(mib, 4, &old_accept_redirects, &datasize, NULL, 0);
&accept_redirects, datasize); if(rc == 0 && old_accept_redirects != accept_redirects) {
else if(old_accept_redirects >= 0) 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, rc = sysctl(mib, 4, NULL, NULL,
&old_accept_redirects, datasize); &old_accept_redirects, datasize);
if(rc == -1) { if(rc == -1) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment