metiscontroller.py 7.34 KB
Newer Older
Greg Rutz's avatar
Greg Rutz committed
1 2 3

import dbus
import gobject
Greg Rutz's avatar
Greg Rutz committed
4
import ConfigParser
Greg Rutz's avatar
Greg Rutz committed
5
from dbus.mainloop.glib import DBusGMainLoop
Greg Rutz's avatar
Greg Rutz committed
6
from subprocess import call
Greg Rutz's avatar
Greg Rutz committed
7 8 9 10

_NETMGR_PATH = '/org/freedesktop/NetworkManager'
_NETMGR_SERVICE = _NETMGR_IF = 'org.freedesktop.NetworkManager'
_NETMGR_DEVICE_IF = 'org.freedesktop.NetworkManager.Device'
11 12 13
_NETMGR_ETH_DEVICE_IF = 'org.freedesktop.NetworkManager.Device.Wired'
_NETMGR_WIFI_DEVICE_IF = 'org.freedesktop.NetworkManager.Device.Wireless'
_NETMGR_ACCESS_POINT_IF = 'org.freedesktop.NetworkManager.AccessPoint'
Greg Rutz's avatar
Greg Rutz committed
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
_DBUS_PROPERTIES = 'org.freedesktop.DBus.Properties'

device_types = { 1: "Ethernet",
                 2: "Wi-Fi",
                 5: "Bluetooth",
                 6: "OLPC",
                 7: "WiMAX",
                 8: "Modem",
                 9: "InfiniBand",
                 10: "Bond",
                 11: "VLAN",
                 12: "ADSL",
                 13: "Bridge",
                 14: "Generic",
                 15: "Team"
               }

device_state = {   0: "Unknown",
	                10: "Unmanaged",
                  20: "Unavailable",
                  30: "Disconnected",
                  40: "Prepare",
                  50: "Config",
                  60: "NeedAuth",
                  70: "IpConfig",
                  80: "IpCheck",
                  90: "Secondaries",
                 100: "Activated",
                 110: "Deactivating",
                 120: "Failed"
}

DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()

Greg Rutz's avatar
Greg Rutz committed
49 50 51
config = ConfigParser.RawConfigParser()
config.readfp(open("../mc.cfg"))

52
metis_ctrl_base = ["metis_control", "-k", "/home/grutz/.ccnx/.ccnx_keystore.p12", "-p", "test"]
Greg Rutz's avatar
Greg Rutz committed
53 54
metis_remove_route = ["remove", "route"]
metis_add_route = ["add", "route"]
Greg Rutz's avatar
Greg Rutz committed
55
metis_add_listener = ["add", "listener", "ether"]
Greg Rutz's avatar
Greg Rutz committed
56
metis_add_connection = ["add", "connection", "ether"]
Greg Rutz's avatar
Greg Rutz committed
57

58 59 60 61 62 63 64 65 66 67 68
class NetworkInterface:

  def __init__(self, device_path):
    self.path = device_path
    self.device = bus.get_object(_NETMGR_SERVICE, device_path)
    self.deviceprops_if = dbus.Interface(self.device, _DBUS_PROPERTIES)
    baseprops = self.deviceprops_if.GetAll(_NETMGR_DEVICE_IF)
    self.device_type = baseprops['DeviceType']

  # Returns a property value for this device.  The base device properties are
  # checked first, followed by the device subtype
Greg Rutz's avatar
Greg Rutz committed
69
  def get_prop(self, propname):
70 71 72 73 74 75 76 77 78 79 80
    baseprops = self.deviceprops_if.GetAll(_NETMGR_DEVICE_IF)
    if propname in baseprops:
      return baseprops[propname]
    else:
      devprops = (self.deviceprops_if.GetAll(_NETMGR_ETH_DEVICE_IF)
                  if self.device_type == 1
                  else self.deviceprops_if.GetAll(_NETMGR_WIFI_DEVICE_IF))
      if propname in devprops:
        return devprops[propname]
    return None

Greg Rutz's avatar
Greg Rutz committed
81 82 83
  def set_prop(self, propname, value):
    self.deviceprops_if.Set(_NETMGR_DEVICE_IF, propname, value)

84 85
network_ifs = {}

Greg Rutz's avatar
Greg Rutz committed
86
def metis_ctrl_execute(cmdlist):
87 88
  print "Executing cmd: ", cmdlist
  call(cmdlist)
Greg Rutz's avatar
Greg Rutz committed
89

90
def metis_connect(ni):
91 92
  if_name = ni.get_prop("Interface")
  print "Making Metis connection for device %s." % if_name
Greg Rutz's avatar
Greg Rutz committed
93

94 95 96 97 98 99
  sym = config.get(if_name, 'symbolic') + "conn"
  cost = config.get(if_name, 'cost')
  print "Adding routes..."
  for prefix in config.get(if_name, 'routes').split(','):
    metis_ctrl_execute(metis_ctrl_base + metis_add_route +
                       [sym] + [prefix] + [config.get(if_name, 'cost')])
Greg Rutz's avatar
Greg Rutz committed
100

Greg Rutz's avatar
Greg Rutz committed
101
def metis_disconnect(ni):
102 103
  if_name = ni.get_prop("Interface")
  print "Metis disconnect for device %s." % if_name
Greg Rutz's avatar
Greg Rutz committed
104

105 106 107 108 109
  print "Removing routes..."
  sym = config.get(if_name, 'symbolic') + "conn"
  for prefix in config.get(if_name, 'routes').split(','):
    metis_ctrl_execute(metis_ctrl_base + metis_remove_route +
                       [sym] + [prefix])
110

Greg Rutz's avatar
Greg Rutz committed
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
# Callback functions
def device_added_cb(device_path):
  device = bus.get_object(_NETMGR_SERVICE, device_path)
  devprops_if = dbus.Interface(device, _DBUS_PROPERTIES)
  devprops = devprops_if.GetAll(_NETMGR_DEVICE_IF)

  print "! ! ! ! ! ! ! ! ! !"
  print ""
  print "Device ADDED"
  print "  Name = %s" % (devprops['Interface'])
  print ""
  print "! ! ! ! ! ! ! ! ! !"

def device_removed_cb(device_path):
  device = bus.get_object(_NETMGR_SERVICE, device_path)
  devprops_if = dbus.Interface(device, _DBUS_PROPERTIES)
  devprops = devprops_if.GetAll(_NETMGR_DEVICE_IF)

  print "! ! ! ! ! ! ! ! ! !"
  print ""
  print "Device REMOVED"
  print "  Name = %s" % (devprops['Interface'])
  print ""
  print "! ! ! ! ! ! ! ! ! !"

136
# Look for change to the "activated" state
Greg Rutz's avatar
Greg Rutz committed
137 138
def device_state_change_cb(new_state, old_state, reason, path):

Greg Rutz's avatar
Greg Rutz committed
139 140
  global network_ifs

141
  ni = network_ifs[path]
Greg Rutz's avatar
Greg Rutz committed
142
  print "%s: %s -> %s (Reason: %d)" % (ni.get_prop("Interface"), device_state[old_state], device_state[new_state], reason)
143

Greg Rutz's avatar
Greg Rutz committed
144
  if old_state != 100 and new_state == 100:
145
    metis_connect(ni)    
Greg Rutz's avatar
Greg Rutz committed
146 147
  elif old_state == 100 and new_state != 100:
    metis_disconnect(ni)
Greg Rutz's avatar
Greg Rutz committed
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175

# Register for NetworkManager signals
nm_matches = []
match = bus.add_signal_receiver(device_added_cb,
                                signal_name="DeviceAdded",
                                dbus_interface=_NETMGR_IF,
                                bus_name=_NETMGR_SERVICE)
nm_matches.append(match)
match = bus.add_signal_receiver(device_removed_cb,
                                signal_name="DeviceRemoved",
                                dbus_interface=_NETMGR_IF,
                                bus_name=_NETMGR_SERVICE)
nm_matches.append(match)

# Device signal matches
dev_matches = {}

# Get the NetworkManager Interface
nm_obj = bus.get_object(_NETMGR_SERVICE, _NETMGR_PATH)
nm_if = dbus.Interface(nm_obj, _NETMGR_IF)

# List all devices
print "================================="
print "         Current Devices         "
print "================================="
print ""
devices = nm_if.GetDevices()
for d in devices:
176
  ni = NetworkInterface(d)
Greg Rutz's avatar
Greg Rutz committed
177
  
178
  # Only wired and WiFi devices for right now
Greg Rutz's avatar
Greg Rutz committed
179
  device_type = ni.get_prop('DeviceType')
180 181 182
  if (not device_type == 1 and not device_type == 2):
    continue

Greg Rutz's avatar
Greg Rutz committed
183
  # Only interfaces specified in our config file
184 185
  if_name = str(ni.get_prop('Interface'))
  if not config.has_section(if_name):
Greg Rutz's avatar
Greg Rutz committed
186 187
    continue;

188 189 190
  # Add to our main list of interfaces
  network_ifs[d] = ni;

191 192
  if_state = ni.get_prop('State')

Greg Rutz's avatar
Greg Rutz committed
193
  print "<<%s>>" % ni.get_prop('Interface')
Greg Rutz's avatar
Greg Rutz committed
194
  print "    path:     %s" % d
Greg Rutz's avatar
Greg Rutz committed
195
  print "    name:     %s" % if_name
Greg Rutz's avatar
Greg Rutz committed
196
  print "    type:     %s" % device_types[device_type]
197
  print "    addr:     %s" % ni.get_prop('HwAddress')
Greg Rutz's avatar
Greg Rutz committed
198
  print "    permaddr: %s" % ni.get_prop('PermHwAddress')
199
  print "    state:    %s" % device_state[if_state]
Greg Rutz's avatar
Greg Rutz committed
200 201 202 203 204 205 206 207 208
  print ""

  match = bus.add_signal_receiver(device_state_change_cb,
                                  signal_name="StateChanged",
                                  dbus_interface=_NETMGR_DEVICE_IF,
                                  bus_name=_NETMGR_SERVICE,
                                  path=d, path_keyword="path")
  dev_matches[d] = match
     
209
  sym = config.get(if_name, 'symbolic')
Greg Rutz's avatar
Greg Rutz committed
210 211 212
  # Add Metis listeners and connection for each and optionally, add routes if 
  # interface is currently connected
  print "Adding listener..."
213 214
  metis_ctrl_execute(metis_ctrl_base + metis_add_listener +
                     [sym + "list"] + [if_name] + ["0xA0A0"])
Greg Rutz's avatar
Greg Rutz committed
215 216
  
  print "Adding connection..."
217 218
  metis_ctrl_execute(metis_ctrl_base + metis_add_connection +
                     [sym + "conn"] + [config.get(if_name, 'nexthop')] + [if_name])
Greg Rutz's avatar
Greg Rutz committed
219

220 221
  # Add routes if currently connected
  if if_state == 100:
Greg Rutz's avatar
Greg Rutz committed
222
    metis_connect(ni)
Greg Rutz's avatar
Greg Rutz committed
223 224 225

gobject.MainLoop().run()