---
 src/connman.h  |    4 ++
 src/ipconfig.c |   89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 93 insertions(+), 0 deletions(-)

diff --git a/src/connman.h b/src/connman.h
index e2b0f1c..2d03a8e 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -249,6 +249,10 @@ int __connman_ipconfig_load(struct connman_ipconfig 
*ipconfig,
 int __connman_ipconfig_save(struct connman_ipconfig *ipconfig,
                GKeyFile *keyfile, const char *identifier, const char *prefix);
 
+int __connman_ipconfig_set_rp_filter(struct connman_ipconfig *ipconfig);
+void __connman_ipconfig_unset_rp_filter(struct connman_ipconfig *ipconfig,
+                                       int old_value);
+
 #include <connman/utsname.h>
 
 int __connman_utsname_set_hostname(const char *hostname);
diff --git a/src/ipconfig.c b/src/ipconfig.c
index fd858a1..f0827f3 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -452,6 +452,95 @@ static void set_ipv6_privacy(gchar *ifname, int value)
        fclose(f);
 }
 
+static int get_rp_filter(const gchar *ifname)
+{
+       gchar *path;
+       FILE *f;
+       int value = -EINVAL, tmp;
+
+       if (ifname == NULL)
+               path = g_strdup("/proc/sys/net/ipv4/conf/all/rp_filter");
+       else
+               path = g_strdup_printf(
+                       "/proc/sys/net/ipv4/conf/%s/rp_filter", ifname);
+
+       if (path == NULL)
+               return -ENOMEM;
+
+       f = fopen(path, "r");
+
+       g_free(path);
+
+       if (f != NULL) {
+               if (fscanf(f, "%d", &tmp) == 1)
+                       value = tmp;
+               fclose(f);
+       }
+
+       return value;
+}
+
+static void set_rp_filter(const gchar *ifname, int value)
+{
+       gchar *path;
+       FILE *f;
+
+       if (ifname == NULL)
+               path = g_strdup("/proc/sys/net/ipv4/conf/all/rp_filter");
+       else
+               path = g_strdup_printf(
+                       "/proc/sys/net/ipv4/conf/%s/rp_filter", ifname);
+
+       if (path == NULL)
+               return;
+
+       f = fopen(path, "r+");
+
+       g_free(path);
+
+       if (f == NULL)
+               return;
+
+       fprintf(f, "%d", value);
+
+       fclose(f);
+}
+
+int __connman_ipconfig_set_rp_filter(struct connman_ipconfig *ipconfig)
+{
+       const char *ifname = NULL;
+       int value;
+
+       if (ipconfig != NULL)
+               ifname = connman_ipconfig_get_ifname(ipconfig);
+
+       value = get_rp_filter(ifname);
+
+       if (value < 0)
+               return value;
+
+       set_rp_filter(ifname, 2);
+
+       connman_info("iface %s rp_filter set to %d",
+                       ifname ? ifname : "<all>", 2);
+
+       return value;
+}
+
+void __connman_ipconfig_unset_rp_filter(struct connman_ipconfig *ipconfig,
+                                       int old_value)
+{
+       const char *ifname = NULL;
+
+       if (ipconfig != NULL)
+               ifname = connman_ipconfig_get_ifname(ipconfig);
+
+       set_rp_filter(ifname, old_value);
+
+       connman_info("iface %s rp_filter restored to %d",
+                       ifname ? ifname : "<all>", old_value);
+}
+
 static void free_ipdevice(gpointer data)
 {
        struct connman_ipdevice *ipdevice = data;
-- 
1.7.1

_______________________________________________
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman

Reply via email to