Commit 99b37d76 authored by Lubomir Rintel's avatar Lubomir Rintel

iface-helper: fix RA processing with more than one router

We construct new IP6Config on each rdisc_config_changed(). That's not a smart
thing to do, since that makes us throw away the previous configuration.

In case the two routers on the same network, the first RA triggers
rdisc_config_changed() for changed gateway and addresses. On handling the
second RA rdisc_config_changed() doesn't add the address, resulting in the
address being removed on ip6 config sync.

A side effect of this is that the address is still tentative, resulting in DAD
retry and an new address being added. So the networking still works, but at the
expense of a single DAD failure and an address that's perhaps different from what
was expected.
parent 0518489b
......@@ -130,9 +130,8 @@ dhcp4_state_changed (NMDhcpClient *client,
static void
rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_data)
{
static NMIP6Config *last_config = NULL;
static NMIP6Config *rdisc_config = NULL;
NMIP6Config *existing;
NMIP6Config *ip6_config;
static int system_support = -1;
guint32 ifa_flags = 0x00;
int i;
......@@ -157,21 +156,25 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da
ifa_flags |= IFA_F_MANAGETEMPADDR;
}
ip6_config = nm_ip6_config_new (ifindex);
existing = nm_ip6_config_capture (ifindex, FALSE, global_opt.tempaddr);
if (rdisc_config)
nm_ip6_config_subtract (existing, rdisc_config);
else
rdisc_config = nm_ip6_config_new (ifindex);
if (changed & NM_RDISC_CONFIG_GATEWAYS) {
/* Use the first gateway as ordered in router discovery cache. */
if (rdisc->gateways->len) {
NMRDiscGateway *gateway = &g_array_index (rdisc->gateways, NMRDiscGateway, 0);
nm_ip6_config_set_gateway (ip6_config, &gateway->address);
nm_ip6_config_set_gateway (rdisc_config, &gateway->address);
} else
nm_ip6_config_set_gateway (ip6_config, NULL);
nm_ip6_config_set_gateway (rdisc_config, NULL);
}
if (changed & NM_RDISC_CONFIG_ADDRESSES) {
/* Rebuild address list from router discovery cache. */
nm_ip6_config_reset_addresses (ip6_config);
nm_ip6_config_reset_addresses (rdisc_config);
/* rdisc->addresses contains at most max_addresses entries.
* This is different from what the kernel does, which
......@@ -193,13 +196,13 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da
address.source = NM_IP_CONFIG_SOURCE_RDISC;
address.n_ifa_flags = ifa_flags;
nm_ip6_config_add_address (ip6_config, &address);
nm_ip6_config_add_address (rdisc_config, &address);
}
}
if (changed & NM_RDISC_CONFIG_ROUTES) {
/* Rebuild route list from router discovery cache. */
nm_ip6_config_reset_routes (ip6_config);
nm_ip6_config_reset_routes (rdisc_config);
for (i = 0; i < rdisc->routes->len; i++) {
NMRDiscRoute *discovered_route = &g_array_index (rdisc->routes, NMRDiscRoute, i);
......@@ -217,7 +220,7 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da
route.source = NM_IP_CONFIG_SOURCE_RDISC;
route.metric = global_opt.priority_v6;
nm_ip6_config_add_route (ip6_config, &route);
nm_ip6_config_add_route (rdisc_config, &route);
}
}
}
......@@ -236,18 +239,9 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da
nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip6_property_path (global_opt.ifname, "mtu"), val);
}
existing = nm_ip6_config_capture (ifindex, FALSE, global_opt.tempaddr);
if (last_config)
nm_ip6_config_subtract (existing, last_config);
nm_ip6_config_merge (existing, ip6_config, NM_IP_CONFIG_MERGE_DEFAULT);
nm_ip6_config_merge (existing, rdisc_config, NM_IP_CONFIG_MERGE_DEFAULT);
if (!nm_ip6_config_commit (existing, ifindex, TRUE))
nm_log_warn (LOGD_IP6, "(%s): failed to apply IPv6 config", global_opt.ifname);
if (last_config)
g_object_unref (last_config);
last_config = nm_ip6_config_new (ifindex);
nm_ip6_config_replace (last_config, ip6_config, NULL);
}
static void
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment