void reset_interface_parameters(interface_t *base_ifp) { if (base_ifp->reset_arp_config && --base_ifp->reset_arp_config == 0) { set_sysctl("net/ipv4/conf", base_ifp->ifname, "arp_ignore", base_ifp->reset_arp_ignore_value); set_sysctl("net/ipv4/conf", base_ifp->ifname, "arp_filter", base_ifp->reset_arp_filter_value); } }
static inline void reset_interface_parameters_sysctl(interface_t *base_ifp) { if (base_ifp->reset_arp_config && --base_ifp->reset_arp_config == 0) { set_sysctl("net/ipv4/conf", base_ifp->ifname, "arp_ignore", (int)base_ifp->arp_ignore); set_sysctl("net/ipv4/conf", base_ifp->ifname, "arp_filter", (int)base_ifp->arp_filter); } }
void restore_rp_filter(void) { list ifs; element e; interface_t *ifp; unsigned rp_filter; #ifdef _HAVE_IPV4_DEVCONF_ sysctl_opts_t rpfilter_sysctl[] = { { IPV4_DEVCONF_RP_FILTER, 1 }, { 0, 0} }; #endif /* Restore the original settings of rp_filter, but only if they * are the same as what we set them to */ if (all_rp_filter == UINT_MAX) return; rp_filter = get_sysctl("net/ipv4/conf", "all", "rp_filter"); if (rp_filter == 0) { log_message(LOG_INFO, "NOTICE: resetting sysctl net.ipv4.conf.all.rp_filter to %d", all_rp_filter); set_sysctl("net/ipv4/conf", "all", "rp_filter", all_rp_filter); } if (default_rp_filter != UINT_MAX) { rp_filter = get_sysctl("net/ipv4/conf", "default", "rp_filter"); if (rp_filter == all_rp_filter) { log_message(LOG_INFO, "NOTICE: resetting sysctl net.ipv4.conf.default.rp_filter to %d", default_rp_filter); set_sysctl("net/ipv4/conf", "default", "rp_filter", default_rp_filter); } default_rp_filter = UINT_MAX; } ifs = get_if_list(); LIST_FOREACH(ifs, ifp, e) { if (ifp->rp_filter != UINT_MAX) { rp_filter = get_sysctl("net/ipv4/conf", ifp->ifname, "rp_filter"); if (rp_filter == all_rp_filter) { #ifdef _HAVE_IPV4_DEVCONF_ rpfilter_sysctl[0].value = ifp->rp_filter; netlink_set_interface_flags(ifp->ifindex, rpfilter_sysctl); #else set_sysctl("net/ipv4/conf", ifp->ifname, "rp_filter", ifp->rp_filter); #endif } } } all_rp_filter = UINT_MAX; }
static inline void set_promote_secondaries_sysctl(interface_t *ifp) { if (get_sysctl("net/ipv4/conf", ifp->ifname, "promote_secondaries") == 1) { ifp->promote_secondaries = true; return; } set_sysctl("net/ipv4/conf", ifp->ifname, "promote_secondaries", 1); }
static inline void set_interface_parameters_sysctl(const interface_t *ifp, interface_t *base_ifp) { unsigned val; set_sysctl("net/ipv4/conf", ifp->ifname, "arp_ignore", 1); set_sysctl("net/ipv4/conf", ifp->ifname, "accept_local", 1); set_sysctl("net/ipv4/conf", ifp->ifname, "rp_filter", 0); set_sysctl("net/ipv4/conf", ifp->ifname, "promote_secondaries", 1); if (base_ifp->reset_arp_config) base_ifp->reset_arp_config++; else { if ((val = get_sysctl("net/ipv4/conf", base_ifp->ifname, "arp_ignore")) != UINT_MAX && (base_ifp->arp_ignore = (uint32_t)val) != 1) set_sysctl("net/ipv4/conf", base_ifp->ifname, "arp_ignore", 1); if ((val = get_sysctl("net/ipv4/conf", base_ifp->ifname, "arp_filter")) != UINT_MAX && (base_ifp->arp_filter = (uint32_t)val) != 1) set_sysctl("net/ipv4/conf", base_ifp->ifname, "arp_filter", 1); base_ifp->reset_arp_config = 1; } }
void set_interface_parameters(const interface_t *ifp, interface_t *base_ifp) { set_sysctl("net/ipv4/conf", ifp->ifname, "arp_ignore", 1); set_sysctl("net/ipv4/conf", ifp->ifname, "accept_local", 1); set_sysctl("net/ipv4/conf", ifp->ifname, "rp_filter", 0); set_sysctl("net/ipv4/conf", ifp->ifname, "promote_secondaries", 1); if (base_ifp->reset_arp_config) base_ifp->reset_arp_config++; else { if ((base_ifp->reset_arp_ignore_value = get_sysctl("net/ipv4/conf", base_ifp->ifname, "arp_ignore")) != 1) set_sysctl("net/ipv4/conf", base_ifp->ifname, "arp_ignore", 1); if ((base_ifp->reset_arp_filter_value = get_sysctl("net/ipv4/conf", base_ifp->ifname, "arp_filter")) != 1) set_sysctl("net/ipv4/conf", base_ifp->ifname, "arp_filter", 1); base_ifp->reset_arp_config = 1; } }
void link_disable_ipv6(const interface_t* ifp) { /* libnl3, nor the kernel, support setting IPv6 options */ set_sysctl("net/ipv6/conf", ifp->ifname, "disable_ipv6", 1); }
void link_set_ipv6(const interface_t* ifp, bool enable) { /* There is no direct way to set IPv6 options */ set_sysctl("net/ipv6/conf", ifp->ifname, "disable_ipv6", enable ? 0 : 1); }
/* IPv4 VMAC interfaces require rp_filter to be 0; this in turn requires * net.ipv4.conf.all.rp_filter to be 0, but if it is non-zero, then all * interfaces will be operating with a non-zero value of rp_filter. * In this function, if all.rp_filter > 0 and default.rp_filter < all.rp_filter, * we first set default.rp_filter to the current value of all.rp_filter, * so that any new interfaces are created with the current value of all.rp_filter. * We then iterate through all interfaces, and if {interface}.rp_filter < all.rp_filter * we set {interface}.rp_filter = all.rp_filter. * Finally we set all.rp_filter = 0. * * This should not alter the operation of any interface, or any interface * subsequently created, but it does allow us to set rp_filter = 0 * on vmac interfaces. */ static void clear_rp_filter(void) { list ifs; element e; interface_t *ifp; unsigned rp_filter; #ifdef _HAVE_IPV4_DEVCONF_ sysctl_opts_t rpfilter_sysctl[] = { { IPV4_DEVCONF_RP_FILTER, 1 }, { 0, 0} }; #endif rp_filter = get_sysctl("net/ipv4/conf", "all", "rp_filter"); if (rp_filter == UINT_MAX) { log_message(LOG_INFO, "Unable to read sysctl net.ipv4.conf.all.rp_filter"); return; } if (rp_filter == 0) return; /* Save current value of all/rp_filter */ all_rp_filter = rp_filter; /* We want to ensure that default/rp_filter is at least the value of all/rp_filter */ rp_filter = get_sysctl("net/ipv4/conf", "default", "rp_filter"); if (rp_filter < all_rp_filter) { log_message(LOG_INFO, "NOTICE: setting sysctl net.ipv4.conf.default.rp_filter from %d to %d", rp_filter, all_rp_filter); set_sysctl("net/ipv4/conf", "default", "rp_filter", all_rp_filter); default_rp_filter = rp_filter; } /* Now ensure rp_filter for all interfaces is at least all/rp_filter. */ #ifdef _HAVE_IPV4_DEVCONF_ rpfilter_sysctl[0].value = all_rp_filter; #endif kernel_netlink_poll(); /* Update our view of interfaces first */ ifs = get_if_list(); LIST_FOREACH(ifs, ifp, e) { if (!ifp->ifindex) continue; #ifndef _HAVE_IPV4_DEVCONF_ if ((ifp->rp_filter = get_sysctl("net/ipv4/conf", ifp->ifname, "rp_filter")) == UINT_MAX) log_message(LOG_INFO, "Unable to read rp_filter for %s", ifp->ifname); else #endif if (ifp->rp_filter < all_rp_filter) { #ifdef _HAVE_IPV4_DEVCONF_ netlink_set_interface_flags(ifp->ifindex, rpfilter_sysctl); #else set_sysctl("net/ipv4/conf", ifp->ifname, "rp_filter", all_rp_filter); #endif } else { /* Indicate we are not setting it */ ifp->rp_filter = UINT_MAX; } } /* We have now made sure that all the interfaces have rp_filter >= all_rp_filter */ log_message(LOG_INFO, "NOTICE: setting sysctl net.ipv4.conf.all.rp_filter from %d to 0", all_rp_filter); set_sysctl("net/ipv4/conf", "all", "rp_filter", 0); }
static inline void reset_promote_secondaries_sysctl(interface_t *ifp) { set_sysctl("net/ipv4/conf", ifp->ifname, "promote_secondaries", 0); }