ip6: add default gateway to NMIP6Config (bgo #676317)
Bug #676317 describes the following error: NetworkManager[30151]: <error> [1337348764.559121] [nm-system.c:1121] nm_system_replace_default_ip6_route(): (eth1): failed to set IPv6 default route: -7 The above error is caused by NetworkManager assuming default gateways belong to addresses but failing to setup default gateways for addresses learned through DHCPv6. This commit doesn't fix the fundamental issue but can be viewed as an ugly workaround that gets IPv6 connection up and running. It doesn't fix the fundamental flaw of binding gateways to IP addresses. They are configured separately in IPv6 and NM should use lifetimes and allow default gateway reconfiguration.
This commit is contained in:

committed by
Dan Williams

parent
1c0e2a1ec3
commit
8a059b1496
@@ -1270,8 +1270,6 @@ nm_ip6_manager_get_ip6_config (NMIP6Manager *manager, int ifindex)
|
||||
struct rtnl_route *rtnlroute;
|
||||
struct nl_addr *nldest, *nlgateway;
|
||||
struct in6_addr *dest, *gateway;
|
||||
gboolean defgw_set = FALSE;
|
||||
struct in6_addr defgw;
|
||||
uint32_t metric;
|
||||
NMIP6Route *ip6route;
|
||||
int i;
|
||||
@@ -1321,11 +1319,9 @@ nm_ip6_manager_get_ip6_config (NMIP6Manager *manager, int ifindex)
|
||||
gateway = nl_addr_get_binary_addr (nlgateway);
|
||||
|
||||
if (rtnl_route_get_dst_len (rtnlroute) == 0) {
|
||||
/* Default gateway route; don't add to normal routes but to each address */
|
||||
if (!defgw_set) {
|
||||
memcpy (&defgw, gateway, sizeof (defgw));
|
||||
defgw_set = TRUE;
|
||||
}
|
||||
/* Default gateway route; cache the router's address for later */
|
||||
if (!nm_ip6_config_get_defgw (config))
|
||||
nm_ip6_config_set_defgw (config, gateway);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1348,6 +1344,8 @@ nm_ip6_manager_get_ip6_config (NMIP6Manager *manager, int ifindex)
|
||||
|
||||
/* Add addresses */
|
||||
for (rtnladdr = FIRST_ADDR (priv->addr_cache); rtnladdr; rtnladdr = NEXT_ADDR (rtnladdr)) {
|
||||
const struct in6_addr *defgw;
|
||||
|
||||
if (rtnl_addr_get_ifindex (rtnladdr) != device->ifindex)
|
||||
continue;
|
||||
|
||||
@@ -1360,8 +1358,9 @@ nm_ip6_manager_get_ip6_config (NMIP6Manager *manager, int ifindex)
|
||||
nm_ip6_address_set_prefix (ip6addr, rtnl_addr_get_prefixlen (rtnladdr));
|
||||
nm_ip6_address_set_address (ip6addr, addr);
|
||||
nm_ip6_config_take_address (config, ip6addr);
|
||||
if (defgw_set)
|
||||
nm_ip6_address_set_gateway (ip6addr, &defgw);
|
||||
defgw = nm_ip6_config_get_defgw (config);
|
||||
if (defgw)
|
||||
nm_ip6_address_set_gateway (ip6addr, defgw);
|
||||
}
|
||||
|
||||
/* Add DNS servers */
|
||||
|
@@ -1794,6 +1794,10 @@ merge_ip6_configs (NMIP6Config *dst, NMIP6Config *src)
|
||||
for (i = 0; i < nm_ip6_config_get_num_nameservers (src); i++)
|
||||
nm_ip6_config_add_nameserver (dst, nm_ip6_config_get_nameserver (src, i));
|
||||
|
||||
/* default gateway */
|
||||
if (!nm_ip6_config_get_defgw (dst))
|
||||
nm_ip6_config_set_defgw (dst, nm_ip6_config_get_defgw (src));
|
||||
|
||||
/* routes */
|
||||
for (i = 0; i < nm_ip6_config_get_num_routes (src); i++)
|
||||
nm_ip6_config_add_route (dst, nm_ip6_config_get_route (src, i));
|
||||
|
@@ -53,6 +53,8 @@ typedef struct {
|
||||
GPtrArray *domains;
|
||||
GPtrArray *searches;
|
||||
|
||||
gboolean defgw_set;
|
||||
struct in6_addr defgw;
|
||||
GSList *routes;
|
||||
|
||||
gboolean never_default;
|
||||
@@ -244,6 +246,30 @@ void nm_ip6_config_reset_nameservers (NMIP6Config *config)
|
||||
g_array_remove_range (priv->nameservers, 0, priv->nameservers->len);
|
||||
}
|
||||
|
||||
void
|
||||
nm_ip6_config_set_defgw (NMIP6Config *config, const struct in6_addr *defgw)
|
||||
{
|
||||
NMIP6ConfigPrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_IP6_CONFIG (config));
|
||||
|
||||
priv = NM_IP6_CONFIG_GET_PRIVATE (config);
|
||||
if (defgw)
|
||||
memcpy (&priv->defgw, defgw, sizeof (priv->defgw));
|
||||
priv->defgw_set = !!defgw;
|
||||
}
|
||||
|
||||
const struct in6_addr *
|
||||
nm_ip6_config_get_defgw (NMIP6Config *config)
|
||||
{
|
||||
NMIP6ConfigPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL);
|
||||
|
||||
priv = NM_IP6_CONFIG_GET_PRIVATE (config);
|
||||
return priv->defgw_set ? &priv->defgw : NULL;
|
||||
}
|
||||
|
||||
void
|
||||
nm_ip6_config_take_route (NMIP6Config *config, NMIP6Route *route)
|
||||
{
|
||||
@@ -659,6 +685,7 @@ nm_ip6_config_init (NMIP6Config *config)
|
||||
priv->nameservers = g_array_new (FALSE, TRUE, sizeof (struct in6_addr));
|
||||
priv->domains = g_ptr_array_sized_new (3);
|
||||
priv->searches = g_ptr_array_sized_new (3);
|
||||
priv->defgw_set = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -67,6 +67,9 @@ const struct in6_addr *nm_ip6_config_get_nameserver (NMIP6Config *config, g
|
||||
guint32 nm_ip6_config_get_num_nameservers (NMIP6Config *config);
|
||||
void nm_ip6_config_reset_nameservers (NMIP6Config *config);
|
||||
|
||||
void nm_ip6_config_set_defgw (NMIP6Config *config, const struct in6_addr *defgw);
|
||||
const struct in6_addr *nm_ip6_config_get_defgw (NMIP6Config *config);
|
||||
|
||||
void nm_ip6_config_take_route (NMIP6Config *config, NMIP6Route *route);
|
||||
void nm_ip6_config_add_route (NMIP6Config *config, NMIP6Route *route);
|
||||
void nm_ip6_config_replace_route (NMIP6Config *config, guint32 i, NMIP6Route *new_route);
|
||||
|
@@ -648,7 +648,12 @@ update_ip6_routing_and_dns (NMPolicy *policy, gboolean force_update)
|
||||
g_assert (ip6_config);
|
||||
addr = nm_ip6_config_get_address (ip6_config, 0);
|
||||
|
||||
nm_system_replace_default_ip6_route (ip_ifindex, nm_ip6_address_get_gateway (addr));
|
||||
if (memcmp (nm_ip6_address_get_gateway (addr)->s6_addr, in6addr_any.s6_addr, sizeof (in6addr_any.s6_addr)) != 0)
|
||||
nm_system_replace_default_ip6_route (ip_ifindex, nm_ip6_address_get_gateway (addr));
|
||||
else if (nm_ip6_config_get_defgw (ip6_config))
|
||||
nm_system_replace_default_ip6_route (ip_ifindex, nm_ip6_config_get_defgw (ip6_config));
|
||||
else
|
||||
nm_log_dbg (LOGD_IP6, "missing default IPv6 route");
|
||||
|
||||
dns_type = NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE;
|
||||
}
|
||||
|
Reference in New Issue
Block a user