| Index: chrome/browser/chromeos/cros/network_library_impl_cros.cc
|
| diff --git a/chrome/browser/chromeos/cros/network_library_impl_cros.cc b/chrome/browser/chromeos/cros/network_library_impl_cros.cc
|
| index 15a1d2c62a155fd3edee3133ffb78a824d9c373f..b0efb580a0a8cce00a5f9bf720b2569d3f6d6772 100644
|
| --- a/chrome/browser/chromeos/cros/network_library_impl_cros.cc
|
| +++ b/chrome/browser/chromeos/cros/network_library_impl_cros.cc
|
| @@ -22,6 +22,16 @@ using content::BrowserThread;
|
|
|
| namespace chromeos {
|
|
|
| +// Structure used to pass IP parameter info to a DoSetIPParameters callback,
|
| +// since Bind only takes up to six parameters.
|
| +struct NetworkLibraryImplCros::IPParameterInfo {
|
| + std::string address;
|
| + std::string netmask;
|
| + std::string gateway;
|
| + std::string name_servers;
|
| + int dhcp_usage_mask;
|
| +};
|
| +
|
| namespace {
|
|
|
| // List of cellular operators names that should have data roaming always enabled
|
| @@ -535,97 +545,42 @@ NetworkIPConfigVector NetworkLibraryImplCros::GetIPConfigs(
|
| return ipconfig_vector;
|
| }
|
|
|
| -void NetworkLibraryImplCros::SetIPConfig(const NetworkIPConfig& ipconfig) {
|
| - if (ipconfig.device_path.empty())
|
| +void NetworkLibraryImplCros::SetIPParameters(const std::string& service_path,
|
| + const std::string& address,
|
| + const std::string& netmask,
|
| + const std::string& gateway,
|
| + const std::string& name_servers,
|
| + int dhcp_usage_mask) {
|
| + if (service_path.empty())
|
| return;
|
|
|
| - VLOG(1) << "Setting IPConfig: " << ipconfig.ToString();
|
| -
|
| - NetworkIPConfig* ipconfig_dhcp = NULL;
|
| - std::string ipconfig_dhcp_path;
|
| - NetworkIPConfig* ipconfig_static = NULL;
|
| - std::string ipconfig_static_path;
|
| -
|
| - NetworkIPConfigVector ipconfigs;
|
| - std::vector<std::string> ipconfig_paths;
|
| - CrosListIPConfigs(ipconfig.device_path, &ipconfigs, &ipconfig_paths, NULL);
|
| - for (size_t i = 0; i < ipconfigs.size(); ++i) {
|
| - if (ipconfigs[i].type == chromeos::IPCONFIG_TYPE_DHCP) {
|
| - ipconfig_dhcp = &ipconfigs[i];
|
| - ipconfig_dhcp_path = ipconfig_paths[i];
|
| - } else if (ipconfigs[i].type == chromeos::IPCONFIG_TYPE_IPV4) {
|
| - ipconfig_static = &ipconfigs[i];
|
| - ipconfig_static_path = ipconfig_paths[i];
|
| - }
|
| - }
|
| -
|
| - NetworkIPConfigVector ipconfigs2;
|
| - std::vector<std::string> ipconfig_paths2;
|
| - if (ipconfig.type == chromeos::IPCONFIG_TYPE_DHCP) {
|
| - // If switching from static to DHCP, create new DHCP IPConfig.
|
| - if (!ipconfig_dhcp &&
|
| - !CrosAddIPConfig(ipconfig.device_path, chromeos::IPCONFIG_TYPE_DHCP)) {
|
| - LOG(ERROR) << "Unable to add new DHCP IPConfig";
|
| - return;
|
| - }
|
| - // User wants DHCP now. So delete the static IPConfig.
|
| - if (ipconfig_static)
|
| - CrosRemoveIPConfig(ipconfig_static_path);
|
| - } else if (ipconfig.type == chromeos::IPCONFIG_TYPE_IPV4) {
|
| - // If switching from DHCP to static, create new static IPConfig.
|
| - if (!ipconfig_static) {
|
| - if (!CrosAddIPConfig(ipconfig.device_path,
|
| - chromeos::IPCONFIG_TYPE_IPV4)) {
|
| - LOG(ERROR) << "Unable to add new static IPConfig";
|
| - return;
|
| - }
|
| - // Now find the newly created IPConfig.
|
| - if (CrosListIPConfigs(ipconfig.device_path, &ipconfigs2,
|
| - &ipconfig_paths2, NULL)) {
|
| - for (size_t i = 0; i < ipconfigs2.size(); ++i) {
|
| - if (ipconfigs2[i].type == chromeos::IPCONFIG_TYPE_IPV4) {
|
| - ipconfig_static = &ipconfigs2[i];
|
| - ipconfig_static_path = ipconfig_paths2[i];
|
| - }
|
| - }
|
| - }
|
| - if (!ipconfig_static) {
|
| - LOG(ERROR) << "Unable to find newly added static IPConfig";
|
| - return;
|
| - }
|
| - }
|
| -
|
| - // Save any changed details.
|
| - if (ipconfig.address != ipconfig_static->address) {
|
| - base::StringValue value(ipconfig.address);
|
| - CrosSetNetworkIPConfigProperty(ipconfig_static_path,
|
| - flimflam::kAddressProperty, value);
|
| - }
|
| - if (ipconfig.netmask != ipconfig_static->netmask) {
|
| - int prefixlen = ipconfig.GetPrefixLength();
|
| - if (prefixlen == -1) {
|
| - VLOG(1) << "IPConfig prefix length is invalid for netmask "
|
| - << ipconfig.netmask;
|
| - } else {
|
| - base::FundamentalValue value(prefixlen);
|
| - CrosSetNetworkIPConfigProperty(ipconfig_static_path,
|
| - flimflam::kPrefixlenProperty, value);
|
| - }
|
| - }
|
| - if (ipconfig.gateway != ipconfig_static->gateway) {
|
| - base::StringValue value(ipconfig.gateway);
|
| - CrosSetNetworkIPConfigProperty(ipconfig_static_path,
|
| - flimflam::kGatewayProperty, value);
|
| - }
|
| - if (ipconfig.name_servers != ipconfig_static->name_servers) {
|
| - base::StringValue value(ipconfig.name_servers);
|
| - CrosSetNetworkIPConfigProperty(ipconfig_static_path,
|
| - flimflam::kNameServersProperty, value);
|
| - }
|
| - // Remove DHCP IPConfig if there is one.
|
| - if (ipconfig_dhcp)
|
| - CrosRemoveIPConfig(ipconfig_dhcp_path);
|
| - }
|
| + VLOG(1) << "Setting IP parameters: "
|
| + << "address: " << address
|
| + << (dhcp_usage_mask & USE_DHCP_ADDRESS ?
|
| + " (ignored)" : " (in use)")
|
| + << "netmask: " << netmask
|
| + << (dhcp_usage_mask & USE_DHCP_NETMASK ?
|
| + " (ignored)" : " (in use)")
|
| + << "gateway: " << gateway
|
| + << (dhcp_usage_mask & USE_DHCP_GATEWAY ?
|
| + " (ignored)" : " (in use)")
|
| + << "name_servers: " << name_servers
|
| + << (dhcp_usage_mask & USE_DHCP_NAME_SERVERS ?
|
| + " (ignored)" : " (in use)");
|
| +
|
| + // Have to pass these in a structure, since Bind only takes up to six
|
| + // parameters.
|
| + IPParameterInfo info;
|
| + info.address = address;
|
| + info.netmask = netmask;
|
| + info.gateway = gateway;
|
| + info.name_servers = name_servers;
|
| + info.dhcp_usage_mask = dhcp_usage_mask;
|
| + chromeos::NetworkPropertiesCallback callback =
|
| + base::Bind(&NetworkLibraryImplCros::SetIPParametersCallback,
|
| + weak_ptr_factory_.GetWeakPtr(), info);
|
| +
|
| + CrosRequestNetworkServiceProperties(service_path, callback);
|
| }
|
|
|
| /////////////////////////////////////////////////////////////////////////////
|
| @@ -1212,4 +1167,123 @@ void NetworkLibraryImplCros::ParseNetworkDevice(const std::string& device_path,
|
| AddNetworkDeviceObserver(device_path, network_device_observer_.get());
|
| }
|
|
|
| +void NetworkLibraryImplCros::SetIPParametersCallback(
|
| + const IPParameterInfo& info,
|
| + const std::string& service_path,
|
| + const base::DictionaryValue* properties) {
|
| + // Find the properties we're going to set, and minimize the DBus calls below
|
| + // by not clearing if it's already cleared, and not setting if it's already
|
| + // set to the same value. Also, don't reconnect at the end if nothing changed.
|
| + bool something_changed = false;
|
| + std::string current_address;
|
| + int32 current_prefixlen = -1;
|
| + std::string current_gateway;
|
| + std::string current_name_servers;
|
| + bool address_exists = properties->GetStringWithoutPathExpansion(
|
| + shill::kStaticIPAddressProperty,
|
| + ¤t_address);
|
| + VLOG_IF(2, address_exists) << shill::kStaticIPAddressProperty
|
| + << "=" << current_address;
|
| + bool prefixlen_exists = properties->GetIntegerWithoutPathExpansion(
|
| + shill::kStaticIPPrefixlenProperty,
|
| + ¤t_prefixlen);
|
| + VLOG_IF(2, prefixlen_exists) << shill::kStaticIPPrefixlenProperty
|
| + << "=" << current_prefixlen;
|
| + bool gateway_exists = properties->GetStringWithoutPathExpansion(
|
| + shill::kStaticIPGatewayProperty,
|
| + ¤t_gateway);
|
| + VLOG_IF(2, gateway_exists) << shill::kStaticIPGatewayProperty
|
| + << "=" << current_gateway;
|
| + bool name_servers_exist = properties->GetStringWithoutPathExpansion(
|
| + shill::kStaticIPNameServersProperty,
|
| + ¤t_name_servers);
|
| + VLOG_IF(2, name_servers_exist) << shill::kStaticIPNameServersProperty
|
| + << "=" << current_name_servers;
|
| +
|
| + if (info.dhcp_usage_mask & USE_DHCP_ADDRESS) {
|
| + if (address_exists) {
|
| + something_changed = true;
|
| + CrosClearNetworkServiceProperty(service_path,
|
| + shill::kStaticIPAddressProperty);
|
| + VLOG(2) << "Clearing " << shill::kStaticIPAddressProperty;
|
| + }
|
| + } else if (current_address != info.address) {
|
| + base::StringValue value(info.address);
|
| + VLOG(2) << "Setting " << shill::kStaticIPAddressProperty
|
| + << " to " << info.address;
|
| + something_changed = true;
|
| + CrosSetNetworkServiceProperty(service_path,
|
| + shill::kStaticIPAddressProperty,
|
| + value);
|
| + }
|
| +
|
| + if (info.dhcp_usage_mask & USE_DHCP_NETMASK) {
|
| + if (prefixlen_exists) {
|
| + something_changed = true;
|
| + CrosClearNetworkServiceProperty(service_path,
|
| + shill::kStaticIPPrefixlenProperty);
|
| + VLOG(2) << "Clearing " << shill::kStaticIPPrefixlenProperty;
|
| + }
|
| + } else {
|
| + int prefixlen = CrosNetmaskToPrefixLength(info.netmask);
|
| + if (prefixlen == -1) {
|
| + VLOG(1) << "IPConfig prefix length is invalid for netmask "
|
| + << info.netmask;
|
| + } else if (current_prefixlen != prefixlen) {
|
| + base::FundamentalValue value(prefixlen);
|
| + VLOG(2) << "Setting " << shill::kStaticIPPrefixlenProperty
|
| + << " to " << prefixlen;
|
| + something_changed = true;
|
| + CrosSetNetworkServiceProperty(service_path,
|
| + shill::kStaticIPPrefixlenProperty,
|
| + value);
|
| + }
|
| + }
|
| +
|
| + if (info.dhcp_usage_mask & USE_DHCP_GATEWAY) {
|
| + if (gateway_exists) {
|
| + something_changed = true;
|
| + CrosClearNetworkServiceProperty(service_path,
|
| + shill::kStaticIPGatewayProperty);
|
| + VLOG(2) << "Clearing " << shill::kStaticIPGatewayProperty;
|
| + }
|
| + } else if (current_gateway != info.gateway){
|
| + base::StringValue value(info.gateway);
|
| + VLOG(2) << "Setting " << shill::kStaticIPGatewayProperty
|
| + << " to " << info.gateway;
|
| + something_changed = true;
|
| + CrosSetNetworkServiceProperty(service_path,
|
| + shill::kStaticIPGatewayProperty,
|
| + value);
|
| + }
|
| +
|
| + if (info.dhcp_usage_mask & USE_DHCP_NAME_SERVERS) {
|
| + if (name_servers_exist) {
|
| + something_changed = true;
|
| + CrosClearNetworkServiceProperty(service_path,
|
| + shill::kStaticIPNameServersProperty);
|
| + VLOG(2) << "Clearing " << shill::kStaticIPNameServersProperty;
|
| + }
|
| + } else if (current_name_servers != info.name_servers){
|
| + base::StringValue value(info.name_servers);
|
| + VLOG(2) << "Setting " << shill::kStaticIPNameServersProperty
|
| + << " to " << info.name_servers;
|
| + something_changed = true;
|
| + CrosSetNetworkServiceProperty(service_path,
|
| + shill::kStaticIPNameServersProperty,
|
| + value);
|
| + }
|
| +
|
| + if (!something_changed)
|
| + return;
|
| +
|
| + // Find the network associated with this service path, and attempt to refresh
|
| + // its IP parameters, so that the changes to the service properties can take
|
| + // effect.
|
| + Network* network = FindNetworkByPath(service_path);
|
| +
|
| + if (network && network->connecting_or_connected())
|
| + RefreshIPConfig(network);
|
| +}
|
| +
|
| } // namespace chromeos
|
|
|