mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-04 22:40:16 +01:00
core: fix routing crash with WWAN/PTP configurations
Some configurations won't have a gateway address, because they are point-to-point (/32). The previous code expected one and asserted if a gateway was not found; but even without the assertion, other code expected a non-NULL gateway. Handle that by defaulting the gateway to 0.0.0.0 (IPv4) or :: (IPv6) and override that with a better gateway if we have one, otherwise just use 0.0.0.0/:: since we already know the IP config we're settings should be the default one.
This commit is contained in:
parent
c0458cb433
commit
3d9d70822c
1 changed files with 33 additions and 21 deletions
|
|
@ -569,10 +569,9 @@ update_ip4_routing (NMPolicy *policy, gboolean force_update)
|
|||
NMVPNConnection *vpn = NULL;
|
||||
NMActiveConnection *best_ac = NULL;
|
||||
NMIP4Config *ip4_config = NULL, *parent_ip4;
|
||||
NMIP4Address *addr = NULL, *tmp_addr;
|
||||
const char *ip_iface = NULL;
|
||||
int ip_ifindex = -1;
|
||||
guint32 parent_mss;
|
||||
guint32 gw_addr = 0, parent_mss;
|
||||
guint32 i;
|
||||
|
||||
/* Note that we might have an IPv4 VPN tunneled over an IPv6-only device,
|
||||
|
|
@ -588,15 +587,18 @@ update_ip4_routing (NMPolicy *policy, gboolean force_update)
|
|||
if (!force_update && best && (best == policy->default_device4))
|
||||
return;
|
||||
|
||||
/* We set the default route to the first gateway we find */
|
||||
/* We set the default route to the first gateway we find. If we don't find
|
||||
* a gateway (WWAN, point-to-point, etc) then we just use 0.0.0.0
|
||||
*/
|
||||
for (i = 0; i < nm_ip4_config_get_num_addresses (ip4_config); i++) {
|
||||
tmp_addr = nm_ip4_config_get_address (ip4_config, i);
|
||||
if (nm_ip4_address_get_gateway (tmp_addr)) {
|
||||
addr = tmp_addr;
|
||||
NMIP4Address *addr;
|
||||
|
||||
addr = nm_ip4_config_get_address (ip4_config, i);
|
||||
if (nm_ip4_address_get_gateway (addr)) {
|
||||
gw_addr = nm_ip4_address_get_gateway (addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_assert (addr);
|
||||
|
||||
if (vpn) {
|
||||
parent = nm_vpn_connection_get_parent_device (vpn);
|
||||
|
|
@ -604,14 +606,14 @@ update_ip4_routing (NMPolicy *policy, gboolean force_update)
|
|||
parent_mss = parent_ip4 ? nm_ip4_config_get_mss (parent_ip4) : 0;
|
||||
|
||||
nm_system_replace_default_ip4_route_vpn (ip_ifindex,
|
||||
nm_ip4_address_get_gateway (addr),
|
||||
gw_addr,
|
||||
nm_vpn_connection_get_ip4_internal_gateway (vpn),
|
||||
nm_ip4_config_get_mss (ip4_config),
|
||||
nm_device_get_ip_ifindex (parent),
|
||||
parent_mss);
|
||||
} else {
|
||||
nm_system_replace_default_ip4_route (ip_ifindex,
|
||||
nm_ip4_address_get_gateway (addr),
|
||||
gw_addr,
|
||||
nm_ip4_config_get_mss (ip4_config));
|
||||
}
|
||||
|
||||
|
|
@ -732,11 +734,11 @@ update_ip6_routing (NMPolicy *policy, gboolean force_update)
|
|||
NMVPNConnection *vpn = NULL;
|
||||
NMActiveConnection *best_ac = NULL;
|
||||
NMIP6Config *ip6_config = NULL, *parent_ip6;
|
||||
NMIP6Address *addr = NULL, *tmp_addr;
|
||||
const char *ip_iface = NULL;
|
||||
int ip_ifindex = -1;
|
||||
guint32 parent_mss;
|
||||
guint32 i;
|
||||
const struct in6_addr *gw_addr;
|
||||
|
||||
/* Note that we might have an IPv6 VPN tunneled over an IPv4-only device,
|
||||
* so we can get (vpn != NULL && best == NULL).
|
||||
|
|
@ -751,15 +753,27 @@ update_ip6_routing (NMPolicy *policy, gboolean force_update)
|
|||
if (!force_update && best && (best == policy->default_device6))
|
||||
return;
|
||||
|
||||
/* We set the default route to the first gateway we find */
|
||||
/* If no better gateway is found, use ::; not all configurations will
|
||||
* have a gateway, especially WWAN/Point-to-Point connections.
|
||||
*/
|
||||
gw_addr = &in6addr_any;
|
||||
|
||||
/* Look for a gateway paired with one of the addresses */
|
||||
for (i = 0; i < nm_ip6_config_get_num_addresses (ip6_config); i++) {
|
||||
tmp_addr = nm_ip6_config_get_address (ip6_config, i);
|
||||
if (nm_ip6_address_get_gateway (tmp_addr)) {
|
||||
addr = tmp_addr;
|
||||
NMIP6Address *addr;
|
||||
|
||||
addr = nm_ip6_config_get_address (ip6_config, i);
|
||||
if (nm_ip6_address_get_gateway (addr)) {
|
||||
gw_addr = nm_ip6_address_get_gateway (addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_assert (addr);
|
||||
|
||||
/* If we don't find a paired gateway, try the generic IPv6 gateway */
|
||||
g_assert (gw_addr);
|
||||
if ( (memcmp (gw_addr->s6_addr, in6addr_any.s6_addr, sizeof (in6addr_any.s6_addr)) == 0)
|
||||
&& nm_ip6_config_get_gateway (ip6_config))
|
||||
gw_addr = nm_ip6_config_get_gateway (ip6_config);
|
||||
|
||||
if (vpn) {
|
||||
parent = nm_vpn_connection_get_parent_device (vpn);
|
||||
|
|
@ -767,18 +781,16 @@ update_ip6_routing (NMPolicy *policy, gboolean force_update)
|
|||
parent_mss = parent_ip6 ? nm_ip6_config_get_mss (parent_ip6) : 0;
|
||||
|
||||
nm_system_replace_default_ip6_route_vpn (ip_ifindex,
|
||||
nm_ip6_address_get_gateway (addr),
|
||||
gw_addr,
|
||||
nm_vpn_connection_get_ip6_internal_gateway (vpn),
|
||||
nm_ip6_config_get_mss (ip6_config),
|
||||
nm_device_get_ip_ifindex (parent),
|
||||
parent_mss);
|
||||
} else {
|
||||
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_gateway (ip6_config))
|
||||
nm_system_replace_default_ip6_route (ip_ifindex, nm_ip6_config_get_gateway (ip6_config));
|
||||
if (gw_addr)
|
||||
nm_system_replace_default_ip6_route (ip_ifindex, gw_addr);
|
||||
else
|
||||
nm_log_dbg (LOGD_IP6, "missing default IPv6 route");
|
||||
nm_log_dbg (LOGD_IP6, "missing default IPv6 gateway");
|
||||
}
|
||||
|
||||
update_default_ac (policy, best_ac, nm_active_connection_set_default6);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue