bearer-mbim: fine-tune bearer IP method reporting
v4: modems/providers may not return DNS servers and not all modems support DHCP, so lack of DNS servers should not indicate a bearer IP method of "DHCP". IP config daemon/scripts already have to handle missing DNS anyway. v6: IPv6 requires SLAAC or DHCPv6 as part of the specification, so for now we assume modems will support it. Provide all the info the modem sent, but if there is any missing information use an IP method of "DHCP" to indicate that info should be obtained via SLAAC/DHCPv6. Only use an IP method of "STATIC" when all basic properties are given by the modem.
This commit is contained in:
@@ -852,13 +852,19 @@ typedef enum { /*< underscore_name=mm_modem_contacts_storage >*/
|
|||||||
/**
|
/**
|
||||||
* MMBearerIpMethod:
|
* MMBearerIpMethod:
|
||||||
* @MM_BEARER_IP_METHOD_UNKNOWN: Unknown method.
|
* @MM_BEARER_IP_METHOD_UNKNOWN: Unknown method.
|
||||||
* @MM_BEARER_IP_METHOD_PPP: Use PPP to get the address.
|
* @MM_BEARER_IP_METHOD_PPP: Use PPP to get IP addresses and DNS information.
|
||||||
|
* For IPv6, use PPP to retrieve the 64-bit Interface Identifier, use the IID to
|
||||||
|
* construct an IPv6 link-local address by following RFC 5072, and then run
|
||||||
|
* DHCP over the PPP link to retrieve DNS settings.
|
||||||
* @MM_BEARER_IP_METHOD_STATIC: Use the provided static IP configuration given
|
* @MM_BEARER_IP_METHOD_STATIC: Use the provided static IP configuration given
|
||||||
* by the modem to configure the IP data interface.
|
* by the modem to configure the IP data interface. Note that DNS servers may
|
||||||
|
* not be provided by the network or modem firmware.
|
||||||
* @MM_BEARER_IP_METHOD_DHCP: Begin DHCP or IPv6 SLAAC on the data interface to
|
* @MM_BEARER_IP_METHOD_DHCP: Begin DHCP or IPv6 SLAAC on the data interface to
|
||||||
* obtain necessary IP configuration details. For IPv4 bearers DHCP should
|
* obtain any necessary IP configuration details that are not already provided
|
||||||
* be used. For IPv6 bearers SLAAC should be used to determine the prefix and
|
* by the IP configuration. For IPv4 bearers DHCP should be used. For IPv6
|
||||||
* any additional details.
|
* bearers SLAAC should be used, and the IP configuration may already contain
|
||||||
|
* a link-local address that should be assigned to the interface before SLAAC
|
||||||
|
* is started to obtain the rest of the configuration.
|
||||||
*
|
*
|
||||||
* Type of IP method configuration to be used in a given Bearer.
|
* Type of IP method configuration to be used in a given Bearer.
|
||||||
*/
|
*/
|
||||||
|
@@ -413,14 +413,13 @@ ip_configuration_query_ready (MbimDevice *device,
|
|||||||
ctx->ip_type == MBIM_CONTEXT_IP_TYPE_IPV4_AND_IPV6) {
|
ctx->ip_type == MBIM_CONTEXT_IP_TYPE_IPV4_AND_IPV6) {
|
||||||
ipv4_config = mm_bearer_ip_config_new ();
|
ipv4_config = mm_bearer_ip_config_new ();
|
||||||
|
|
||||||
/* We assume that if we have IP and DNS, we can setup static */
|
/* We assume that if we have an IP we can use static configuration.
|
||||||
|
* Not all modems or providers will return DNS servers or even a
|
||||||
|
* gateway, and not all modems support DHCP either. The IP management
|
||||||
|
* daemon/script just has to deal with this...
|
||||||
|
*/
|
||||||
if (ipv4configurationavailable & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_ADDRESS &&
|
if (ipv4configurationavailable & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_ADDRESS &&
|
||||||
ipv4configurationavailable & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS &&
|
ipv4addresscount > 0) {
|
||||||
ipv4addresscount > 0 &&
|
|
||||||
ipv4dnsservercount > 0) {
|
|
||||||
gchar **strarr;
|
|
||||||
guint i, n;
|
|
||||||
|
|
||||||
mm_bearer_ip_config_set_method (ipv4_config, MM_BEARER_IP_METHOD_STATIC);
|
mm_bearer_ip_config_set_method (ipv4_config, MM_BEARER_IP_METHOD_STATIC);
|
||||||
|
|
||||||
/* IP address, pick the first one */
|
/* IP address, pick the first one */
|
||||||
@@ -441,8 +440,15 @@ ip_configuration_query_ready (MbimDevice *device,
|
|||||||
g_free (str);
|
g_free (str);
|
||||||
g_object_unref (addr);
|
g_object_unref (addr);
|
||||||
}
|
}
|
||||||
|
} else
|
||||||
|
mm_bearer_ip_config_set_method (ipv4_config, MM_BEARER_IP_METHOD_DHCP);
|
||||||
|
|
||||||
|
/* DNS */
|
||||||
|
if (ipv4configurationavailable & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS &&
|
||||||
|
ipv4dnsservercount > 0) {
|
||||||
|
gchar **strarr;
|
||||||
|
guint i, n;
|
||||||
|
|
||||||
/* DNS */
|
|
||||||
strarr = g_new0 (gchar *, ipv4dnsservercount + 1);
|
strarr = g_new0 (gchar *, ipv4dnsservercount + 1);
|
||||||
for (i = 0, n = 0; i < ipv4dnsservercount; i++) {
|
for (i = 0, n = 0; i < ipv4dnsservercount; i++) {
|
||||||
addr = g_inet_address_new_from_bytes ((guint8 *)&ipv4dnsserver[i], G_SOCKET_FAMILY_IPV4);
|
addr = g_inet_address_new_from_bytes ((guint8 *)&ipv4dnsserver[i], G_SOCKET_FAMILY_IPV4);
|
||||||
@@ -452,8 +458,7 @@ ip_configuration_query_ready (MbimDevice *device,
|
|||||||
}
|
}
|
||||||
mm_bearer_ip_config_set_dns (ipv4_config, (const gchar **)strarr);
|
mm_bearer_ip_config_set_dns (ipv4_config, (const gchar **)strarr);
|
||||||
g_strfreev (strarr);
|
g_strfreev (strarr);
|
||||||
} else
|
}
|
||||||
mm_bearer_ip_config_set_method (ipv4_config, MM_BEARER_IP_METHOD_DHCP);
|
|
||||||
|
|
||||||
/* MTU */
|
/* MTU */
|
||||||
if (ipv4configurationavailable & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_MTU)
|
if (ipv4configurationavailable & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_MTU)
|
||||||
@@ -465,30 +470,28 @@ ip_configuration_query_ready (MbimDevice *device,
|
|||||||
if (ctx->ip_type == MBIM_CONTEXT_IP_TYPE_IPV6 ||
|
if (ctx->ip_type == MBIM_CONTEXT_IP_TYPE_IPV6 ||
|
||||||
ctx->ip_type == MBIM_CONTEXT_IP_TYPE_IPV4V6 ||
|
ctx->ip_type == MBIM_CONTEXT_IP_TYPE_IPV4V6 ||
|
||||||
ctx->ip_type == MBIM_CONTEXT_IP_TYPE_IPV4_AND_IPV6) {
|
ctx->ip_type == MBIM_CONTEXT_IP_TYPE_IPV4_AND_IPV6) {
|
||||||
|
gboolean address_set = FALSE;
|
||||||
|
gboolean gateway_set = FALSE;
|
||||||
|
gboolean dns_set = FALSE;
|
||||||
|
|
||||||
ipv6_config = mm_bearer_ip_config_new ();
|
ipv6_config = mm_bearer_ip_config_new ();
|
||||||
|
|
||||||
/* We assume that if we have IP and DNS, we can setup static */
|
|
||||||
if (ipv6configurationavailable & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_ADDRESS &&
|
if (ipv6configurationavailable & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_ADDRESS &&
|
||||||
ipv6configurationavailable & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS &&
|
ipv6addresscount > 0) {
|
||||||
ipv6addresscount > 0 &&
|
|
||||||
ipv6dnsservercount > 0) {
|
|
||||||
gchar **strarr;
|
|
||||||
guint i, n;
|
|
||||||
|
|
||||||
mm_bearer_ip_config_set_method (ipv6_config, MM_BEARER_IP_METHOD_STATIC);
|
|
||||||
|
|
||||||
/* IP address, pick the first one */
|
/* IP address, pick the first one */
|
||||||
addr = g_inet_address_new_from_bytes ((guint8 *)&ipv6address[0]->ipv6_address, G_SOCKET_FAMILY_IPV6);
|
addr = g_inet_address_new_from_bytes ((guint8 *)&ipv6address[0]->ipv6_address, G_SOCKET_FAMILY_IPV6);
|
||||||
str = g_inet_address_to_string (addr);
|
str = g_inet_address_to_string (addr);
|
||||||
mm_bearer_ip_config_set_address (ipv6_config, str);
|
mm_bearer_ip_config_set_address (ipv6_config, str);
|
||||||
g_free (str);
|
g_free (str);
|
||||||
|
address_set = TRUE;
|
||||||
|
|
||||||
/* If the address is a link-local one, then SLAAC or DHCP must be used
|
/* If the address is a link-local one, then SLAAC or DHCP must be used
|
||||||
* to get the real prefix and address. Change the method to DHCP to
|
* to get the real prefix and address.
|
||||||
* indicate this to clients.
|
* FIXME: maybe the modem reported non-LL address in ipv6address[1] ?
|
||||||
*/
|
*/
|
||||||
if (g_inet_address_get_is_link_local (addr))
|
if (g_inet_address_get_is_link_local (addr))
|
||||||
mm_bearer_ip_config_set_method (ipv6_config, MM_BEARER_IP_METHOD_DHCP);
|
address_set = FALSE;
|
||||||
|
|
||||||
g_object_unref (addr);
|
g_object_unref (addr);
|
||||||
|
|
||||||
@@ -502,7 +505,14 @@ ip_configuration_query_ready (MbimDevice *device,
|
|||||||
mm_bearer_ip_config_set_gateway (ipv6_config, str);
|
mm_bearer_ip_config_set_gateway (ipv6_config, str);
|
||||||
g_free (str);
|
g_free (str);
|
||||||
g_object_unref (addr);
|
g_object_unref (addr);
|
||||||
|
gateway_set = TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipv6configurationavailable & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS &&
|
||||||
|
ipv6dnsservercount > 0) {
|
||||||
|
gchar **strarr;
|
||||||
|
guint i, n;
|
||||||
|
|
||||||
/* DNS */
|
/* DNS */
|
||||||
strarr = g_new0 (gchar *, ipv6dnsservercount + 1);
|
strarr = g_new0 (gchar *, ipv6dnsservercount + 1);
|
||||||
@@ -514,12 +524,22 @@ ip_configuration_query_ready (MbimDevice *device,
|
|||||||
}
|
}
|
||||||
mm_bearer_ip_config_set_dns (ipv6_config, (const gchar **)strarr);
|
mm_bearer_ip_config_set_dns (ipv6_config, (const gchar **)strarr);
|
||||||
g_strfreev (strarr);
|
g_strfreev (strarr);
|
||||||
} else
|
|
||||||
mm_bearer_ip_config_set_method (ipv6_config, MM_BEARER_IP_METHOD_DHCP);
|
dns_set = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* MTU */
|
/* MTU */
|
||||||
if (ipv6configurationavailable & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_MTU)
|
if (ipv6configurationavailable & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_MTU)
|
||||||
mm_bearer_ip_config_set_mtu (ipv6_config, ipv6mtu);
|
mm_bearer_ip_config_set_mtu (ipv6_config, ipv6mtu);
|
||||||
|
|
||||||
|
/* Only use the static method if all basic properties are available,
|
||||||
|
* otherwise use DHCP to indicate the missing ones should be
|
||||||
|
* retrieved from SLAAC or DHCPv6.
|
||||||
|
*/
|
||||||
|
if (address_set && gateway_set && dns_set)
|
||||||
|
mm_bearer_ip_config_set_method (ipv6_config, MM_BEARER_IP_METHOD_STATIC);
|
||||||
|
else
|
||||||
|
mm_bearer_ip_config_set_method (ipv6_config, MM_BEARER_IP_METHOD_DHCP);
|
||||||
} else
|
} else
|
||||||
ipv6_config = NULL;
|
ipv6_config = NULL;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user