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 <t...@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 _______________________________________________ Babel-users mailing list Babel-users@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/babel-users