+static void system_set_rpfilter(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/rp_filter", dev->ifname, val);
+}
+
+static void system_set_acceptlocal(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/accept_local", dev->ifname, val);
+}
+
+static void system_set_igmpversion(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/proc/sys/net/ipv4/conf/%s/force_igmp_version", dev->ifname, val);
+}
+
+static void system_set_mldversion(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/proc/sys/net/ipv6/conf/%s/force_mld_version", dev->ifname, val);
+}
+
+static void system_set_neigh4reachabletime(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/base_reachable_time_ms", dev->ifname, val);
+}
+
+static void system_set_neigh6reachabletime(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/proc/sys/net/ipv6/neigh/%s/base_reachable_time_ms", dev->ifname, val);
+}
+
+static void system_set_neigh4gcstaletime(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/gc_stale_time", dev->ifname, val);
+}
+
+static void system_set_neigh6gcstaletime(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/proc/sys/net/ipv6/neigh/%s/gc_stale_time", dev->ifname, val);
+}
+
+static void system_set_dadtransmits(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/proc/sys/net/ipv6/conf/%s/dad_transmits", dev->ifname, val);
+}
+
+static void system_bridge_set_multicast_to_unicast(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/sys/class/net/%s/brport/multicast_to_unicast", dev->ifname, val);
+}
+
+static void system_bridge_set_multicast_fast_leave(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/sys/class/net/%s/brport/multicast_fast_leave", dev->ifname, val);
+}
+
+static void system_bridge_set_hairpin_mode(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/sys/class/net/%s/brport/hairpin_mode", dev->ifname, val);
+}
+
+static void system_bridge_set_multicast_router(struct device *dev, const char *val, bool bridge)
+{
+ system_set_dev_sysctl(bridge ? "/sys/class/net/%s/bridge/multicast_router" :
+ "/sys/class/net/%s/brport/multicast_router",
+ dev->ifname, val);
+}
+
+static void system_bridge_set_robustness(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_startup_query_count",
+ dev->ifname, val);
+ system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_last_member_count",
+ dev->ifname, val);
+}
+
+static void system_bridge_set_query_interval(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_query_interval",
+ dev->ifname, val);
+}
+
+static void system_bridge_set_query_response_interval(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_query_response_interval",
+ dev->ifname, val);
+}
+
+static void system_bridge_set_last_member_interval(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_last_member_interval",
+ dev->ifname, val);
+}
+
+static void system_bridge_set_membership_interval(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_membership_interval",
+ dev->ifname, val);
+}
+
+static void system_bridge_set_other_querier_timeout(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_querier_interval",
+ dev->ifname, val);
+}
+
+static void system_bridge_set_startup_query_interval(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_startup_query_interval",
+ dev->ifname, val);
+}
+
+static void system_bridge_set_learning(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/sys/class/net/%s/brport/learning", dev->ifname, val);
+}
+
+static void system_bridge_set_unicast_flood(struct device *dev, const char *val)
+{
+ system_set_dev_sysctl("/sys/class/net/%s/brport/unicast_flood", dev->ifname, val);
+}
+
+static int system_get_sysctl(const char *path, char *buf, const size_t buf_sz)
+{
+ int fd = -1, ret = -1;
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ goto out;
+
+ ssize_t len = read(fd, buf, buf_sz - 1);
+ if (len < 0)
+ goto out;
+
+ ret = buf[len] = 0;
+
+out:
+ if (fd >= 0)
+ close(fd);
+
+ return ret;
+}
+
+static int
+system_get_dev_sysctl(const char *path, const char *device, char *buf, const size_t buf_sz)
+{
+ snprintf(dev_buf, sizeof(dev_buf), path, device);
+ return system_get_sysctl(dev_buf, buf, buf_sz);
+}
+
+static int system_get_disable_ipv6(struct device *dev, char *buf, const size_t buf_sz)
+{
+ return system_get_dev_sysctl("/proc/sys/net/ipv6/conf/%s/disable_ipv6",
+ dev->ifname, buf, buf_sz);
+}
+
+static int system_get_rpfilter(struct device *dev, char *buf, const size_t buf_sz)
+{
+ return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/rp_filter",
+ dev->ifname, buf, buf_sz);
+}
+
+static int system_get_acceptlocal(struct device *dev, char *buf, const size_t buf_sz)
+{
+ return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/accept_local",
+ dev->ifname, buf, buf_sz);
+}
+
+static int system_get_igmpversion(struct device *dev, char *buf, const size_t buf_sz)
+{
+ return system_get_dev_sysctl("/proc/sys/net/ipv4/conf/%s/force_igmp_version",
+ dev->ifname, buf, buf_sz);
+}
+
+static int system_get_mldversion(struct device *dev, char *buf, const size_t buf_sz)
+{
+ return system_get_dev_sysctl("/proc/sys/net/ipv6/conf/%s/force_mld_version",
+ dev->ifname, buf, buf_sz);
+}
+
+static int system_get_neigh4reachabletime(struct device *dev, char *buf, const size_t buf_sz)
+{
+ return system_get_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/base_reachable_time_ms",
+ dev->ifname, buf, buf_sz);
+}
+
+static int system_get_neigh6reachabletime(struct device *dev, char *buf, const size_t buf_sz)
+{
+ return system_get_dev_sysctl("/proc/sys/net/ipv6/neigh/%s/base_reachable_time_ms",
+ dev->ifname, buf, buf_sz);
+}
+
+static int system_get_neigh4gcstaletime(struct device *dev, char *buf, const size_t buf_sz)
+{
+ return system_get_dev_sysctl("/proc/sys/net/ipv4/neigh/%s/gc_stale_time",
+ dev->ifname, buf, buf_sz);
+}
+
+static int system_get_neigh6gcstaletime(struct device *dev, char *buf, const size_t buf_sz)
+{
+ return system_get_dev_sysctl("/proc/sys/net/ipv6/neigh/%s/gc_stale_time",
+ dev->ifname, buf, buf_sz);
+}
+
+static int system_get_dadtransmits(struct device *dev, char *buf, const size_t buf_sz)
+{
+ return system_get_dev_sysctl("/proc/sys/net/ipv6/conf/%s/dad_transmits",
+ dev->ifname, buf, buf_sz);
+}
+