dhcp_apply_config.py
Go to the documentation of this file.
00001 #! /usr/bin/env python
00002 
00003 import system
00004 from twisted.internet.defer import inlineCallbacks, DeferredLock
00005 from twisted.internet import reactor
00006 from state_publisher import CompositeStatePublisher
00007 from netlink_monitor import netlink_monitor, IFSTATE
00008 import ip_rule
00009 
00010 # FIXME Allow anybody to call shutdown.
00011 
00012 class _DhcpSetterCommon:
00013     # Provides support common code for shutting down on shutdown, and
00014     # handles locking.
00015     def __init__(self):
00016         self._lock = DeferredLock()
00017         self.is_shutdown = False
00018         reactor.addSystemEventTrigger('before', 'shutdown', self._shutdown)
00019     
00020     @inlineCallbacks
00021     def _cb(self, old_state, new_state):
00022         if self.is_shutdown:
00023             return
00024         yield self._lock.acquire()
00025         try:
00026             yield self._locked_cb(old_state, new_state)
00027         finally:
00028             self._lock.release()
00029     
00030     @inlineCallbacks
00031     def _shutdown(self):
00032         #print "Shutdown", self
00033         yield self._cb(None, None)
00034         self.is_shutdown = True
00035 
00036 class DhcpAddressSetter(_DhcpSetterCommon):
00037     def __init__(self, iface, state_pub):
00038         _DhcpSetterCommon.__init__(self)
00039         self.iface = iface
00040         self._iface_status_pub = netlink_monitor.get_status_publisher(iface)
00041         state_pub.subscribe(self._cb)
00042 
00043     @inlineCallbacks
00044     def _locked_cb(self, old_state, new_state):
00045         #print "Address", self.iface, new_state
00046         if new_state is None or old_state is not None:
00047             if self._iface_status_pub.get() >= IFSTATE.PLUGGED:
00048                 yield system.system('ifconfig', self.iface, '0.0.0.0')
00049 
00050         if new_state is not None:
00051             ip = new_state['ip']
00052             ip_slashed = new_state['ip_slashed']
00053             yield system.system('ip', 'addr', 'add', ip_slashed, 'dev', self.iface)
00054             # Send both request and response gratuitous arp.
00055             yield system.system('arping', '-q', '-c', '1', '-A', '-I', self.iface, ip)
00056             yield system.system('arping', '-q', '-c', '1', '-U', '-I', self.iface, ip)
00057 
00058 class DhcpRouteSetter(_DhcpSetterCommon):
00059     def __init__(self, iface, table, state_pub):
00060         _DhcpSetterCommon.__init__(self)
00061         self.iface = iface
00062         self.table = str(table)
00063         self._iface_status_pub = netlink_monitor.get_status_publisher(iface)
00064         CompositeStatePublisher(lambda (addr, dhcp): None if not addr else dhcp, [
00065             netlink_monitor.get_state_publisher(iface, IFSTATE.ADDR),
00066             state_pub
00067         ]).subscribe(self._cb)
00068 
00069     @inlineCallbacks
00070     def _locked_cb(self, old_state, new_state):
00071         if self._iface_status_pub.get() >= IFSTATE.PLUGGED:
00072             yield system.system('ip', 'route', 'flush', 'table', self.table, 'dev', self.iface)
00073 
00074         if new_state:
00075             gateway = new_state['gateway']
00076             ip = new_state['ip']
00077             network_slashed = new_state['network_slashed']
00078             yield system.system('ip', 'route', 'add', 'table', self.table, 'default', 'dev', self.iface, 'via', gateway, 'src', ip, 'onlink')
00079             yield system.system('ip', 'route', 'add', 'table', self.table, network_slashed, 'dev', self.iface, 'src', ip)
00080 
00081 class DhcpSourceRuleSetter:
00082     def __init__(self, iface, table, priority):
00083         self._ip_rule = ip_rule.IpRule(priority)
00084         self.table = str(table)
00085         self.state_pub = self._ip_rule.state_pub
00086         netlink_monitor.get_state_publisher(iface, IFSTATE.ADDR).subscribe(self._cb)
00087         
00088     def _cb(self, old_state, new_state):
00089         if new_state:
00090             ip = new_state[0]
00091             self._ip_rule.set('table', self.table, 'from', ip+"/32")
00092         else:
00093             self._ip_rule.set()


multi_interface_roam
Author(s): Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:18