blob: 298659e4e3d86ab536557c1766a37eb4a808db17 [file] [log] [blame]
#!/bin/env python
# Copyright 2015 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import dbus
SHILL_SERVICE_NAME = 'org.chromium.flimflam'
INTERFACE_MANAGER = 'org.chromium.flimflam.Manager'
INTERFACE_SERVICE = 'org.chromium.flimflam.Service'
STATIC_IP_CONFIG_KEY = 'StaticIPConfig'
SAVED_IP_CONFIG_KEY = 'SavedIPConfig'
NAME_SERVERS_KEY = 'NameServers'
LOCAL_NAME_SERVER = '127.0.0.1'
def main():
bus = dbus.SystemBus()
manager = bus.get_object(SHILL_SERVICE_NAME, '/')
i_manager = dbus.Interface(manager, INTERFACE_MANAGER)
ethernet_path = i_manager.FindMatchingService({'Type': 'ethernet'})
ethernet_service = bus.get_object(SHILL_SERVICE_NAME, ethernet_path)
i_ethernet_service = dbus.Interface(ethernet_service, INTERFACE_SERVICE)
properties = i_ethernet_service.GetProperties()
# We must merge the nameservers received over DHCP with the extra nameserver
# we want to install.
static_ip_config = properties.get(STATIC_IP_CONFIG_KEY, {})
static_name_servers = static_ip_config.get(NAME_SERVERS_KEY, [])
saved_ip_config = properties.get(SAVED_IP_CONFIG_KEY, {})
saved_name_servers = saved_ip_config.get(NAME_SERVERS_KEY, [])
# By keeping LOCAL_NAME_SERVER first, dnsmasq can forward requests to any
# number of entries below. OTOH, if we keep the local nameserver last, there's
# a chance that we'll hit the maximum number of entries allowed in
# resolv.conf, and never make it to the local nameserver.
merged_name_servers = [dbus.String(LOCAL_NAME_SERVER)] + saved_name_servers
# NB: Careful now -- this script is usually launched by an upstart job every
# time shill connects. This means that by toggling shill's connection state,
# we're eventually relaunching this script. Therefore, we must ensure that we
# don't keep toggling shill when no new changes are made to the nameservers.
if set(merged_name_servers) == set(static_name_servers):
print('List of static nameservers is up-to-date. Exiting early.')
return
static_ip_config[NAME_SERVERS_KEY] = merged_name_servers
i_ethernet_service.SetProperty(STATIC_IP_CONFIG_KEY, static_ip_config)
# If we updated the nameservers, we need to toggle the service connection to
# pick up the new nameservers.
try:
i_ethernet_service.Disconnect()
finally:
i_ethernet_service.Connect()
if __name__ == '__main__':
main()