merge: branch 'bg/ipv6-accept-ra-rh1734470'

https://bugzilla.redhat.com/show_bug.cgi?id=1734470

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/247
(cherry picked from commit 6cf28fe2c0)
This commit is contained in:
Beniamino Galvani 2019-11-15 16:18:30 +01:00
commit b35fb49a28
7 changed files with 107 additions and 25 deletions

View file

@ -9667,6 +9667,18 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in
if (changed & NM_NDISC_CONFIG_HOP_LIMIT)
nm_platform_sysctl_ip_conf_set_ipv6_hop_limit_safe (nm_device_get_platform (self), nm_device_get_ip_iface (self), rdata->hop_limit);
if (changed & NM_NDISC_CONFIG_REACHABLE_TIME) {
nm_platform_sysctl_ip_neigh_set_ipv6_reachable_time (nm_device_get_platform (self),
nm_device_get_ip_iface (self),
rdata->reachable_time_ms);
}
if (changed & NM_NDISC_CONFIG_RETRANS_TIMER) {
nm_platform_sysctl_ip_neigh_set_ipv6_retrans_time (nm_device_get_platform (self),
nm_device_get_ip_iface (self),
rdata->retrans_timer_ms);
}
if (changed & NM_NDISC_CONFIG_MTU) {
if (priv->ip6_mtu != rdata->mtu) {
_LOGD (LOGD_DEVICE, "mtu: set IPv6 MTU to %u", (guint) rdata->mtu);
@ -9728,24 +9740,11 @@ addrconf6_start_with_link_ready (NMDevice *self)
if (!ip_config_merge_and_apply (self, AF_INET6, TRUE))
_LOGW (LOGD_IP6, "failed to apply manual IPv6 configuration");
/* FIXME: These sysctls would probably be better set by the lndp ndisc itself. */
switch (nm_ndisc_get_node_type (priv->ndisc)) {
case NM_NDISC_NODE_TYPE_HOST:
/* Accepting prefixes from discovered routers. */
nm_device_sysctl_ip_conf_set (self, AF_INET6, "accept_ra", "1");
nm_device_sysctl_ip_conf_set (self, AF_INET6, "accept_ra_defrtr", "0");
nm_device_sysctl_ip_conf_set (self, AF_INET6, "accept_ra_pinfo", "0");
nm_device_sysctl_ip_conf_set (self, AF_INET6, "accept_ra_rtr_pref", "0");
break;
case NM_NDISC_NODE_TYPE_ROUTER:
/* We're the router. */
if (nm_ndisc_get_node_type (priv->ndisc) == NM_NDISC_NODE_TYPE_ROUTER) {
nm_device_sysctl_ip_conf_set (self, AF_INET6, "forwarding", "1");
nm_device_activate_schedule_ip_config_result (self, AF_INET6, NULL);
priv->needs_ip6_subnet = TRUE;
g_signal_emit (self, signals[IP6_SUBNET_NEEDED], 0);
break;
default:
g_assert_not_reached ();
}
priv->ndisc_changed_id = g_signal_connect (priv->ndisc,
@ -9856,9 +9855,6 @@ save_ip6_properties (NMDevice *self)
{
static const char *const ip6_properties_to_save[] = {
"accept_ra",
"accept_ra_defrtr",
"accept_ra_pinfo",
"accept_ra_rtr_pref",
"forwarding",
"disable_ipv6",
"hop_limit",
@ -10183,6 +10179,7 @@ act_stage3_ip_config_start (NMDevice *self,
set_nm_ipv6ll (self, TRUE);
/* Re-enable IPv6 on the interface */
nm_device_sysctl_ip_conf_set (self, AF_INET6, "accept_ra", "0");
set_disable_ipv6 (self, "0");
/* Synchronize external IPv6 configuration with kernel, since
@ -14811,7 +14808,6 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason, CleanupType clean
/* Turn off kernel IPv6 */
if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) {
set_disable_ipv6 (self, "1");
nm_device_sysctl_ip_conf_set (self, AF_INET6, "accept_ra", "0");
nm_device_sysctl_ip_conf_set (self, AF_INET6, "use_tempaddr", "0");
}
@ -15103,9 +15099,7 @@ ip6_managed_setup (NMDevice *self)
{
set_nm_ipv6ll (self, TRUE);
set_disable_ipv6 (self, "1");
nm_device_sysctl_ip_conf_set (self, AF_INET6, "accept_ra_defrtr", "0");
nm_device_sysctl_ip_conf_set (self, AF_INET6, "accept_ra_pinfo", "0");
nm_device_sysctl_ip_conf_set (self, AF_INET6, "accept_ra_rtr_pref", "0");
nm_device_sysctl_ip_conf_set (self, AF_INET6, "accept_ra", "0");
nm_device_sysctl_ip_conf_set (self, AF_INET6, "use_tempaddr", "0");
nm_device_sysctl_ip_conf_set (self, AF_INET6, "forwarding", "0");
}

View file

@ -116,6 +116,7 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
gint32 now = nm_utils_get_monotonic_timestamp_s ();
int offset;
int hop_limit;
guint32 val;
/* Router discovery is subject to the following RFC documents:
*
@ -294,6 +295,18 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
changed |= NM_NDISC_CONFIG_HOP_LIMIT;
}
val = ndp_msgra_reachable_time (msgra);
if (val && rdata->public.reachable_time_ms != val) {
rdata->public.reachable_time_ms = val;
changed |= NM_NDISC_CONFIG_REACHABLE_TIME;
}
val = ndp_msgra_retransmit_time (msgra);
if (val && rdata->public.retrans_timer_ms != val) {
rdata->public.retrans_timer_ms = val;
changed |= NM_NDISC_CONFIG_RETRANS_TIMER;
}
/* MTU */
ndp_msg_opt_for_each_offset(offset, msg, NDP_MSG_OPT_MTU) {
guint32 mtu = ndp_msg_opt_mtu(msg, offset);

View file

@ -1039,6 +1039,14 @@ _config_changed_log (NMNDisc *ndisc, NMNDiscConfigMap changed)
config_map_to_string (changed, changedstr);
_LOGD ("neighbor discovery configuration changed [%s]:", changedstr);
_LOGD (" dhcp-level %s", dhcp_level_to_string (priv->rdata.public.dhcp_level));
if (rdata->public.hop_limit)
_LOGD (" hop limit : %d", rdata->public.hop_limit);
if (rdata->public.reachable_time_ms)
_LOGD (" reachable time : %u", (guint) rdata->public.reachable_time_ms);
if (rdata->public.retrans_timer_ms)
_LOGD (" retrans timer : %u", (guint) rdata->public.retrans_timer_ms);
for (i = 0; i < rdata->gateways->len; i++) {
NMNDiscGateway *gateway = &g_array_index (rdata->gateways, NMNDiscGateway, i);

View file

@ -112,6 +112,8 @@ typedef enum {
NM_NDISC_CONFIG_DNS_DOMAINS = 1 << 5,
NM_NDISC_CONFIG_HOP_LIMIT = 1 << 6,
NM_NDISC_CONFIG_MTU = 1 << 7,
NM_NDISC_CONFIG_REACHABLE_TIME = 1 << 8,
NM_NDISC_CONFIG_RETRANS_TIMER = 1 << 9,
} NMNDiscConfigMap;
typedef enum {
@ -137,6 +139,8 @@ typedef struct {
NMNDiscDHCPLevel dhcp_level;
guint32 mtu;
int hop_limit;
guint32 reachable_time_ms;
guint32 retrans_timer_ms;
guint gateways_n;
guint addresses_n;

View file

@ -220,6 +220,18 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in
if (changed & NM_NDISC_CONFIG_HOP_LIMIT)
nm_platform_sysctl_ip_conf_set_ipv6_hop_limit_safe (NM_PLATFORM_GET, global_opt.ifname, rdata->hop_limit);
if (changed & NM_NDISC_CONFIG_REACHABLE_TIME) {
nm_platform_sysctl_ip_neigh_set_ipv6_reachable_time (NM_PLATFORM_GET,
global_opt.ifname,
rdata->reachable_time_ms);
}
if (changed & NM_NDISC_CONFIG_RETRANS_TIMER) {
nm_platform_sysctl_ip_neigh_set_ipv6_retrans_time (NM_PLATFORM_GET,
global_opt.ifname,
rdata->retrans_timer_ms);
}
if (changed & NM_NDISC_CONFIG_MTU) {
nm_platform_sysctl_ip_conf_set_int64 (NM_PLATFORM_GET,
AF_INET6,
@ -557,10 +569,7 @@ main (int argc, char *argv[])
if (iid)
nm_ndisc_set_iid (ndisc, *iid);
nm_platform_sysctl_ip_conf_set (NM_PLATFORM_GET, AF_INET6, global_opt.ifname, "accept_ra", "1");
nm_platform_sysctl_ip_conf_set (NM_PLATFORM_GET, AF_INET6, global_opt.ifname, "accept_ra_defrtr", "0");
nm_platform_sysctl_ip_conf_set (NM_PLATFORM_GET, AF_INET6, global_opt.ifname, "accept_ra_pinfo", "0");
nm_platform_sysctl_ip_conf_set (NM_PLATFORM_GET, AF_INET6, global_opt.ifname, "accept_ra_rtr_pref", "0");
nm_platform_sysctl_ip_conf_set (NM_PLATFORM_GET, AF_INET6, global_opt.ifname, "accept_ra", "0");
g_signal_connect (NM_PLATFORM_GET,
NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED,

View file

@ -610,6 +610,54 @@ nm_platform_sysctl_ip_conf_set_ipv6_hop_limit_safe (NMPlatform *self,
return TRUE;
}
gboolean
nm_platform_sysctl_ip_neigh_set_ipv6_reachable_time (NMPlatform *self,
const char *iface,
guint value_ms)
{
char path[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
char str[128];
guint clamped;
_CHECK_SELF (self, klass, FALSE);
if (!value_ms)
return TRUE;
/* RFC 4861 says the value can't be greater than one hour.
* Also use a reasonable lower threshold. */
clamped = NM_CLAMP (value_ms, 100, 3600000);
nm_sprintf_buf (path, "/proc/sys/net/ipv6/neigh/%s/base_reachable_time_ms", iface);
nm_sprintf_buf (str, "%u", clamped);
if (!nm_platform_sysctl_set (self, NMP_SYSCTL_PATHID_ABSOLUTE (path), str))
return FALSE;
/* Set stale time in the same way as kernel */
nm_sprintf_buf (path, "/proc/sys/net/ipv6/neigh/%s/gc_stale_time", iface);
nm_sprintf_buf (str, "%u", clamped * 3 / 1000);
return nm_platform_sysctl_set (self, NMP_SYSCTL_PATHID_ABSOLUTE (path), str);
}
gboolean
nm_platform_sysctl_ip_neigh_set_ipv6_retrans_time (NMPlatform *self,
const char *iface,
guint value_ms)
{
char path[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
char str[128];
_CHECK_SELF (self, klass, FALSE);
if (!value_ms)
return TRUE;
nm_sprintf_buf (path, "/proc/sys/net/ipv6/neigh/%s/retrans_time_ms", iface);
nm_sprintf_buf (str, "%u", NM_CLAMP (value_ms, 10, 3600000));
return nm_platform_sysctl_set (self, NMP_SYSCTL_PATHID_ABSOLUTE (path), str);
}
/**
* nm_platform_sysctl_get:
* @self: platform instance

View file

@ -1353,6 +1353,12 @@ gboolean nm_platform_sysctl_ip_conf_set_int64 (NMPlatform *self,
gboolean nm_platform_sysctl_ip_conf_set_ipv6_hop_limit_safe (NMPlatform *self,
const char *iface,
int value);
gboolean nm_platform_sysctl_ip_neigh_set_ipv6_reachable_time (NMPlatform *self,
const char *iface,
guint value_ms);
gboolean nm_platform_sysctl_ip_neigh_set_ipv6_retrans_time (NMPlatform *self,
const char *iface,
guint value_ms);
int nm_platform_sysctl_ip_conf_get_rp_filter_ipv4 (NMPlatform *platform,
const char *iface,
gboolean consider_all,