class Root(Handler):
+ def __init__(self):
+ f = file("/proc/sys/net/ipv4/ip_forward","w")
+ f.write("1")
+ f.close()
+ #self.ip.device_up_hook(self.dns)
+
firewall = FirewallHandler(
pickle_dir = join(pickle_path, 'firewall'),
config_dir = join(config_path, 'firewall'))
--- /dev/null
+#ESPECIFICACION DEL PROTOCOLO DEL PYMIN
+
+[PARAMETROS OPCIONALES]
+<PARAMETROS OBLIGATORIOS>
+
+----------------------------------
+
+MODULO : DHCP
+
+para inciar/parar el servicio :
+dhcp start
+dhcp stop
+
+para setear parametros:
+dhcp set <PARAMETER> <VALUE>
+PARAMETER puede tomar los siguientes valores :
+domain_name : nombre de dominio
+dns_1 : dominio del dns primario
+dns_2 : dominio del dns secundario
+net_address : direccion de red
+net_mask : mascara de la direccion de red
+net_start : direccion de inicio del rango
+net_end : direccion de fin del rango
+net_gateway : direccion del gateway
+
+para crear un host:
+dhcp host add <NAME> <IP> <MAC>
+para eliminar un host:
+dhcp host delete <NAME>
+
+
+NAME : es el nombre del host
+IP : la direccion ip del host
+MAC : la direccion mac del host
+
+-----------------------------------
+
+MODULO : DNS
+
+para inciar/parar el servicio :
+dns start
+dns stop
+
+para setear parametros:
+dns set <PARAMETER> <VALUE>
+PARAMETER puede tomar los siguientes valores :
+isp_dns1 : dns primario del isp
+isp_dns2 : dns secundario del isp
+bind_addr1 : direccion primaria a la cual bindear
+bind_addr2 : direccion secundaria a la cual bindear
+
+para crear una zona:
+dns zone add <ZONE>
+
+para eliminar una zona:
+dns zone delete <ZONE>
+
+para agregar un host a una zona:
+dns host add <ZONE> <HOSTNAME> <IP_HOST>
+
+para eliminar un host de una zona:
+dns host delete <ZONE> <HOSTNAME>
+
+para agregar un mail exchanger:
+dns mx add <ZONE> <MAILEXCHANGER> <PRIO>
+
+para eliminar un mail exchanger:
+dns mx delete <ZONE> <MAILEXCHANGER>
+
+para agregar un name server:
+dns ns add <ZONE> <NAMESERVER>
+
+para eliminar un name server:
+dns ns delete <ZONE> <NAMESERVER>
+
+ZONE : es el nombre de la zona a crear (ej : mizona.com)
+HOSTNAME : nombre del host
+IP_HOST : ip del host
+MAILEXCHANGER : es un mail exchanger (ej: mx1.mizona.com)
+PRIO : es la prioridad sobre el mail exchanger
+NAMESERVER : es un name server (ej: ns1.mizona.com)
+
+-----------------------------------
+
+MODULO : IP
+
+para levantar un device :
+ip dev up <DEVICE>
+
+para bajar un device :
+ip dev down <DEVICE>
+
+para agregar una direccion ip :
+ip addr add <DEVICE> <IP> <PREFIX> [BROADCAST]
+
+para eliminar una direccion ip :
+ip addr add <DEVICE> <IP>
+
+para ver las direcciones ip asignadas a un device:
+ip addr show <DEVICE>
+
+para agregar una ruta :
+ip route add <NETADDR> <PREFIX> <GATEWAY> [DEVICE]
+
+para eliminar una ruta:
+ip route delete <ROUTEINDEX> [DEVICE]
+
+para ver las rutas asignadas:
+ip route show [DEVICE]
+ACLARACION : si una ruta fue dada de alta sin especificar un device,
+la misma podra verse con "ip route show", caso contrario hay
+que especificar el device
+
+para agregar un hop:
+ip hop add <GATEWAY> <DEVICE>
+
+para eliminar un hop:
+ip hop delete <GATEWAY> <DEVICE>
+
+para ver los hops :
+ip hop show <DEVICE>
+
+
+DEVICE : el device (ej: eth0)
+IP : direccion ip
+PREFIX : prefijo de la direccion ip
+BROADCAST : direccion de broadcast (ocpional)
+NETADDR : direccion de red
+GATEWAY : direccion del gateway
+ROUTEINDEX : es el indice de la lista que muestra el comando show
+
+---------------------------------
+
+MODULO : PPP
+
+para inciar/parar el servicio :
+ppp start
+ppp stop
+
+para agregar un coneccion :
+ppp conn add <NAME> <USERNAME> <PASSWORD> <TYPE> [device=<DEVICE>] [server=<SERVER>]
+
+para eliminar una coneccion :
+ppp conn delete <NAME>
+
+para mostrar las conecciones:
+ppp show
+
+NAME : npmbre de la coneccion
+USERNAME : nombre de usuario
+PASSWORD : contraseña
+TYPE : tipo de coneccion punto a punto, la misma puede ser :
+ OE : para pppoe , en este caso debera especificarse un device
+ TUNNEL : para ppptp , en este caso debera especificarse un server
+ PPP : para ppp , en este caso debera especificarse un device
+
+---------------------------------
+
+MODULO : PROXY
+
+para inciar/parar el servicio :
+proxy start
+proxy stop
+
+para setear parametros:
+proxy set <PARAMETER> <VALUE>
+PARAMETER puede tomar los siguientes valores :
+ip : direccion ip
+port : puerto en donde se esucucha
+
+para agregar un host:
+proxy host add <IP>
+
+para eliminar un host:
+proxy host delete <IP>
+
+para ver los hosts:
+proxy host show
+
+para agregar un user:
+proxy user add <USERNAME> <PASSWORD>
+
+para eliminar un user:
+proxy user add <USERNAME>
+
+para ver los usuarios:
+proxy user show
+
+IP: la direccion ip del host
+USERNAME : nombre de usuario
+PASSWORD : contraseña
+
+---------------------------------
+
+MODULO : VRRP
+
+para inciar/parar el servicio :
+vrrp start
+vrrp stop
+
+para setear parametros:
+vrrp set <PARAMETER> <VALUE>
+PARAMETER puede tomar los siguientes valores :
+ipaddress : direccion ip
+id : id dentro del grupo
+prio : prioridad router
+dev : device
+
+---------------------------------
+
+MODULO : FIREWALL
+
+para iniciar/parar el servicio:
+firewall start
+firewall stop
+(el stop elimina todas las reglas y deja todo abierto)
+
+Para agregar una regla:
+firewall rule add <CHAIN> <TARGET> [<SRC> <DST> <PROTOCOL> <SRC_PORT> <DST_PORT>]
+<CHAIN> puede ser: INPUT, OUTPUT o FORWARD
+<TARGET> puede ser: ACCEPT, REJECT o DROP
+<SRC> es la subred fuente (de la forma IP/máscara)
+<DST> es la subred destino (de la forma IP/máscara)
+<PROTOCOL> es: ICMP, UDP, TCP o ALL
+<SRC_PORT> es el puerto fuente (solo válido si <PROTOCOL> es UDP o TCP)
+<DST_PORT> es el puerto destino (solo válido si <PROTOCOL> es UDP o TCP)
+
+Para modificar una regla:
+firewall rule update <INDEX> [<CHAIN> <TARGET> <SRC> <DST> <PROTOCOL> <SRC_PORT> <DST_PORT>]
+<INDEX> es la posición de la regla (puede verse con 'firewall rule show')
+El resto de los parámetros son iguales que para agregar una regla.
+
+Para borrar una regla:
+firewall rule delete <INDEX>
+<INDEX> es la posición de la regla (puede verse con 'firewall rule show')
+
+Para borrar todas las reglas:
+firewall rule clear
+
+Para obtener información sobre una regla:
+firewall rule get <INDEX>
+<INDEX> es la posición de la regla (puede verse con 'firewall rule show')
+
+Para listar (obtener sobre todas) las reglas:
+firewall rule show
+
+---------------------------------
+
+MODULO : NAT
+
+para iniciar/parar el servicio:
+nat start
+nat stop
+(el stop elimina todas las reglas)
+
+Para agregar una redirección de un puerto:
+nat forward add <DEV> <PROTOCOL> <PORT> <DST> [<DST_PORT> <SRC_NET> <DST_NET>]
+<DEV> es el dispositivo de red a usar (por ej eth1)
+<PROTOCOL> es TCP o UDP
+<PORT> es el puerto entrante a redireccionar
+<DST> es la IP de destino a donde redireccionar el puerto
+<DST_PORT> es el puerto destino (si no se especifica, es el mismo que <PORT>)
+<SRC_NET> es la subred fuente para la cual aplicar le redireccionamiento (IP/máscara)
+<DST_NET> es la subred destino para la cual aplicar le redireccionamiento (IP/máscara)
+(si no se especifican subredes, se redirecciona todo el tráfico para el puerto)
+
+Para modificar una redirección de un puerto:
+nat forward update <INDEX> [<DEV> <PROTOCOL> <PORT> <DST> <DST_PORT> <SRC_NET> <DST_NET>]
+<INDEX> es la posición de la redirección (puede verse con 'nat forward show')
+El resto de los parámetros son iguales que para agregar una redirección.
+
+Para borrar una redirección:
+nat forward delete <INDEX>
+<INDEX> es la posición de la redirección (puede verse con 'nat forward show')
+
+Para borrar todas las redirecciones:
+nat forward clear
+
+Para obtener información sobre una redirección:
+nat forward get <INDEX>
+<INDEX> es la posición de la redirección (puede verse con 'nat forward show')
+
+Para listar (obtener información sobre todas) las redirecciones:
+nat forward show
+
+
+Para agregar un source nat:
+nat snat add <DEV> <SRC> [<SRC_NET>]
+<DEV> es el dispositivo de red a usar (por ej eth1)
+<SRC> dirección IP fuente a NATear
+<SRC_NET> es la subred fuente para la cual aplicar el source nat (IP/máscara)
+(si no se especifica subred, se redirecciona todo el tráfico de la IP fuente)
+
+Para modificar un snat:
+nat snat update <INDEX> [<DEV> <PROTOCOL> <PORT> <DST> <DST_PORT> <SRC_NET> <DST_NET>]
+<INDEX> es la posición del snat (puede verse con 'nat snat show')
+El resto de los parámetros son iguales que para agregar un snat.
+
+Para borrar un snat:
+nat snat delete <INDEX>
+<INDEX> es la posición del snat (puede verse con 'nat snat show')
+
+Para borrar todos los snat:
+nat snat clear
+
+Para obtener información sobre un snat:
+nat snat get <INDEX>
+<INDEX> es la posición del snat (puede verse con 'nat snat show')
+
+Para listar (obtener información sobre todos) los snat:
+nat snat show
+
+
+Para agregar un enmascaramiento (masquerade):
+nat masq add <DEV> <SRC_NET>
+<DEV> es el dispositivo de red a usar (por ej eth1)
+<SRC_NET> es la subred fuente para la cual aplicar el masq (IP/máscara)
+
+Para modificar un masq:
+nat masq update <INDEX> [<DEV> <DST_NET>]
+<INDEX> es la posición del snat (puede verse con 'nat masq show')
+El resto de los parámetros son iguales que para agregar un masq.
+
+Para borrar un masq:
+nat masq delete <INDEX>
+<INDEX> es la posición del masq (puede verse con 'nat masq show')
+
+Para borrar todos los masq:
+nat masq clear
+
+Para obtener información sobre un masq:
+nat masq get <INDEX>
+<INDEX> es la posición del masq (puede verse con 'nat masq show')
+
+Para listar (obtener información sobre todos) los masq:
+nat masq show
+
+
+
self.net_addr = net_addr
self.prefix = prefix
self.gateway = gateway
+
def update(self, net_addr=None, prefix=None, gateway=None):
if net_addr is not None: self.net_addr = net_addr
if prefix is not None: self.prefix = prefix
if gateway is not None: self.gateway = gateway
+
def as_tuple(self):
return(self.net_addr, self.prefix, self.gateway)
+ def __cmp__(self, other):
+ if self.net_addr == other.net_addr \
+ and self.prefix == other.prefix \
+ and self.gateway == other.gateway:
+ return 0
+ return cmp(id(self), id(other))
+
class RouteHandler(ListComposedSubHandler):
handler_help = u"Manage IP routes"
_comp_subhandler_cont = 'devices'
_comp_subhandler_attr = 'routes'
_comp_subhandler_class = Route
+ @handler(u'Adds a route to : ip route add <net_addr> <prefix> <gateway> [device]')
+ def add(self, net_addr, prefix, gateway, dev=None):
+ if dev is not None:
+ ListComposedSubHandler.add(self, dev, net_addr, prefix, gateway)
+ else:
+ r = Route(net_addr, prefix, gateway)
+ if not r in self.parent.no_device_routes:
+ self.parent.no_device_routes.append(r)
+
+ @handler("Deletes a route : ip route delete <route_number_in_show> [dev]")
+ def delete(self, index, dev=None):
+ if dev is not None:
+ ListComposedSubHandler.delete(self, dev, index)
+ else:
+ i = int(index)
+ del self.parent.no_device_routes[i]
+
+ @handler("Shows routes : ip route show [dev]")
+ def show(self, dev=None):
+ if dev is not None:
+ return ListComposedSubHandler.show(self, dev)
+ else:
+ return self.parent.no_device_routes
class AddressHandler(DictComposedSubHandler):
handler_help = u"Manage IP addresses"
def up(self, name):
if name in self.parent.devices:
call(self.device_template.render(dev=name, action='up'), shell=True)
+ #bring up all the route asocitaed to the device
+ for route in self.parent.devices[name].routes:
+ try:
+ call(self.parent._render_config('route_add', dict(
+ dev = name,
+ net_addr = route.net_addr,
+ prefix = route.prefix,
+ gateway = route.gateway,
+ )
+ ), shell=True)
+ except ExecutionError, e:
+ print e
+ self.parent._bring_up_no_dev_routes()
+ self.parent._restart_services()
else:
raise DeviceNotFoundError(name)
def down(self, name):
if name in self.parent.devices:
call(self.device_template.render(dev=name, action='down'), shell=True)
+ self.parent._bring_up_no_dev_routes()
+ self.parent._restart_services()
else:
raise DeviceNotFoundError(name)
handler_help = u"Manage IP devices, addresses, routes and hops"
- _persistent_attrs = ('devices','hops')
+ _persistent_attrs = ('devices','hops','no_device_routes')
_restorable_defaults = dict(
devices=get_network_devices(),
- hops = list()
+ hops = list(),
+ no_device_routes = list(),
)
_config_writer_files = ('device', 'ip_add', 'ip_del', 'ip_flush',
self.route = RouteHandler(self)
self.dev = DeviceHandler(self)
self.hop = HopHandler(self)
+ self.no_device_routes = list()
+ self.services = list()
def _write_config(self):
r"_write_config() -> None :: Execute all commands."
for device in self.devices.values():
+ if device.active:
+ self._write_config_for_device(device)
+ self._bring_up_no_dev_routes()
+ self._write_hops()
+
+ def _bring_up_no_dev_routes(self):
+ for route in self.no_device_routes:
try:
- call(self._render_config('route_flush', dict(dev=device.name)), shell=True)
- except ExecutionError, e:
- print e
- try:
- call(self._render_config('ip_flush', dict(dev=device.name)), shell=True)
+ call(self._render_config('route_add', dict(
+ dev = None,
+ net_addr = route.net_addr,
+ prefix = route.prefix,
+ gateway = route.gateway,
+ )
+ ), shell=True)
except ExecutionError, e:
print e
- for address in device.addrs.values():
- broadcast = address.broadcast
- if broadcast is None:
- broadcast = '+'
- try:
- call(self._render_config('ip_add', dict(
- dev = device.name,
- addr = address.ip,
- netmask = address.netmask,
- peer = address.peer,
- broadcast = broadcast,
- )
- ), shell=True)
- except ExecutionError, e:
- print e
- for route in device.routes:
- try:
- call(self._render_config('route_add', dict(
- dev = device.name,
- net_addr = route.net_addr,
- prefix = route.prefix,
- gateway = route.gateway,
- )
- ), shell=True)
- except ExecutionError, e:
- print e
+
+ def _write_hops(self):
+ r"_write_hops() -> None :: Execute all hops."
if self.hops:
try:
call('ip route del default', shell=True)
except ExecutionError, e:
print e
try:
+ #get hops for active devices
+ active_hops = dict()
+ for h in self.hops:
+ if h.device in self.devices:
+ if self.devices[h.device].active:
+ active_hops.append(h)
call(self._render_config('hop', dict(
- hops = self.hops,
+ hops = active_hops,
)
), shell=True)
except ExecutionError, e:
print e
+ def _write_config_for_device(self, device):
+ r"_write_config_for_device(self, device) -> None :: Execute all commands for a device."
+ try:
+ call(self._render_config('route_flush', dict(dev=device.name)), shell=True)
+ except ExecutionError, e:
+ print e
+ try:
+ call(self._render_config('ip_flush', dict(dev=device.name)), shell=True)
+ except ExecutionError, e:
+ print e
+ for address in device.addrs.values():
+ broadcast = address.broadcast
+ if broadcast is None:
+ broadcast = '+'
+ try:
+ call(self._render_config('ip_add', dict(
+ dev = device.name,
+ addr = address.ip,
+ netmask = address.netmask,
+ peer = address.peer,
+ broadcast = broadcast,
+ )
+ ), shell=True)
+ except ExecutionError, e:
+ print e
+ for route in device.routes:
+ try:
+ call(self._render_config('route_add', dict(
+ dev = device.name,
+ net_addr = route.net_addr,
+ prefix = route.prefix,
+ gateway = route.gateway,
+ )
+ ), shell=True)
+ except ExecutionError, e:
+ print e
def handle_timer(self):
self.refresh_devices()
def refresh_devices(self):
devices = get_network_devices()
- #add not registered devices
+ #add not registered and active devices
+ go_active = False
for k,v in devices.items():
if k not in self.devices:
self.devices[k] = v
- #delete dead devices
+ elif not self.devices[k].active:
+ self.active = True
+ go_active = True
+ self._write_config_for_device(self.devices[k])
+ if go_active:
+ self._write_hops()
+ self._bring_up_no_dev_routes()
+ self._restart_services()
+
+ #mark inactive devices
for k in self.devices.keys():
+ go_down = False
if k not in devices:
- del self.devices[k]
+ self.devices[k].active = False
+ go_down = True
+ if go_down:
+ self._bring_up_no_dev_routes()
+
+ def _restart_services(self):
+ for s in self.services:
+ if s._service_running:
+ try:
+ s.stop()
+ except ExecutionError:
+ pass
+ try:
+ s.start()
+ except ExecutionError:
+ pass
+
+ #hooks a service to the ip handler, so when
+ #a device is brought up one can restart the service
+ #that need to refresh their device list
+ def device_up_hook(self, serv):
+ if hasattr(serv, 'stop') and hasattr(serv, 'start'):
+ self.services.append(serv)
+
+
-ip route add dev ${dev} ${net_addr}/${prefix} via ${gateway}
\ No newline at end of file
+%if dev is not None:
+ip route add dev ${dev} ${net_addr}/${prefix} via ${gateway}
+%else:
+ip route add ${net_addr}/${prefix} via ${gateway}
+%endif
\ No newline at end of file
from pymin.services.util import Restorable, ConfigWriter, InitdHandler, \
TransactionalHandler, SubHandler, call, \
get_network_devices, ListComposedSubHandler, \
- DictComposedSubHandler
+ DictComposedSubHandler, ExecutionError
__ALL__ = ('QoSHandler',)
+class DeviceError(HandlerError):
+
+ def __init__(self, dev):
+ self.message = u'Devive error : "%s"' % dev
+
+
+class DeviceNotFoundError(DeviceError):
+
+ def __init__(self, dev):
+ self.message = u'Device not found : "%s"' % dev
+
+
class ClassError(HandlerError):
- def __init__(self, qosclass):
- self.message = u'Class error : "%s"' % qosclass
+ def __init__(self, cls):
+ self.message = u'Class error : "%s"' % cls
class ClassNotFoundError(ClassError):
- def __init__(self, qosclass):
- self.message = u'Class not found : "%s"' % qosclass
+ def __init__(self, cls):
+ self.message = u'Class not found : "%s"' % cls
class ClassAlreadyExistsError(ClassError):
- def __init__(self, qosclass):
- self.message = u'Class already exists : "%s"' % qosclass
+ def __init__(self, cls):
+ self.message = u'Class already exists : "%s"' % cls
+
+
+class HostError(HandlerError):
+
+ def __init__(self, host):
+ self.message = u'Host error : "%s"' % host
+
+
+class HostNotFoundError(HostError):
+
+ def __init__(self, ip):
+ self.message = u'Host not found : "%s"' % host
+
+
+class HostAlreadyExistsError(HostError):
+
+ def __init__(self, ip):
+ self.message = u'Host already exists : "%s"' % host
class Class(Sequence):
def __init__(self, cid, rate=None):
self.cid = cid
self.rate = rate
- self.hosts = list()
+ self.hosts = dict()
def as_tuple(self):
return (self.cid, self.rate)
self.parent = parent
@handler('Adds a class : add <id> <device> <rate>')
- def add(self, cid, dev, rate):
+ def add(self, dev, cid, rate):
if not dev in self.parent.devices:
- raise DeviceNotFoundError(device)
- c = Class(cid, dev, rate)
+ raise DeviceNotFoundError(dev)
+
try:
- self.parent.classes.index(c)
- raise ClassAlreadyExistsError(cid + '->' + dev)
+ self.parent.devices[dev].classes[cid] = Class(cid, rate)
except ValueError:
- self.parent.classes.append(c)
+ raise ClassAlreadyExistsError(cid + ' -> ' + dev)
@handler(u'Deletes a class : delete <id> <device>')
- def delete(self, cid, dev):
+ def delete(self, dev, cid):
if not dev in self.parent.devices:
- raise DeviceNotFoundError(device)
- c = Class(cid, dev)
+ raise DeviceNotFoundError(dev)
+
try:
- self.parent.classes.remove(c)
- except ValueError:
- raise ClassNotFoundError(cid + '->' + dev)
+ del self.parent.devices[dev].classes[cid]
+ except KeyError:
+ raise ClassNotFoundError(cid + ' -> ' + dev)
@handler(u'Lists classes : list <dev>')
- def list(self, device):
+ def list(self, dev):
try:
- k = self.parent.classes.keys()
- except ValueError:
- k = list()
- return k
-
- @handler(u'Get information about all classes: show <dev>')
- def show(self, device):
- try:
- k = self.parent.classes.values()
- except ValueError:
- k = list()
+ k = self.parent.devices[dev].classes.items()
+ except KeyError:
+ k = dict()
return k
def as_tuple(self):
return (self.ip)
+ def __cmp__(self, other):
+ if self.ip == other.ip:
+ return 0
+ return cmp(id(self), id(other))
+
+
+class HostHandler(SubHandler):
-class HostHandler(DictComposedSubHandler):
- handler_help = u"Manage Hosts"
- _comp_subhandler_cont = 'classes'
- _comp_subhandler_attr = 'hosts'
- _comp_subhandler_class = Host
+ def __init__(self, parent):
+ self.parent = parent
+
+ @handler('Adds a host to a class : add <device> <class id> <ip>')
+ def add(self, dev, cid, ip):
+ if not dev in self.parent.devices:
+ raise DeviceNotFoundError(dev)
+
+ if not cid in self.parent.devices[dev].classes:
+ raise ClassNotFoundError(cid)
+
+ try:
+ self.parent.devices[dev].classes[cid].hosts[ip] = Host(ip)
+ except ValueError:
+ raise HostAlreadyExistsError(h + ' -> ' + dev)
+
+ @handler(u'Lists hosts : list <dev> <class id>')
+ def list(self, dev, cid):
+ try:
+ k = self.parent.devices[dev].classes[cid].hosts.keys()
+ except KeyError:
+ k = dict()
+ return k
class Device(Sequence):
def __init__(self, name, mac):
self.name = name
self.mac = mac
- self.classes = list()
+ self.classes = dict()
def as_tuple(self):
return (self.name, self.mac)
@handler(u'Bring the device up')
def up(self, name):
if name in self.parent.devices:
- call(self.device_template.render(dev=name, action='add'), shell=True)
+ try:
+ call(self.device_template.render(dev=name, action='add'), shell=True)
+ except ExecutionError:
+ pass
else:
raise DeviceNotFoundError(name)
@handler(u'Bring the device down')
def down(self, name):
if name in self.parent.devices:
- call(self.device_template.render(dev=name, action='del'), shell=True)
+ try:
+ call(self.device_template.render(dev=name, action='del'), shell=True)
+ except ExecutionError:
+ pass
else:
raise DeviceNotFoundError(name)
handler_help = u"Manage QoS devices, classes and hosts"
- _persistent_attrs = ('devices','classes','hosts')
+ _persistent_attrs = ('devices')
_restorable_defaults = dict(
devices=dict((dev, Device(dev, mac))
- for (dev, mac) in get_network_devices().items()),
- classes = list(),
- hosts = list()
+ for (dev, mac) in get_network_devices().items())
)
_config_writer_files = ('device', 'class_add', 'class_del', 'host_add')
self._restore()
self._write_config()
self.dev = DeviceHandler(self)
- self.classes = ClassHandler(self)
- self.hosts = HostHandler(self)
+ self.cls = ClassHandler(self)
+ self.host = HostHandler(self)
def _write_config(self):
r"_write_config() -> None :: Execute all commands."
for device in self.devices.values():
- call(self._render_config('device', dict(dev=device.name, action='del')), shell=True)
- call(self._render_config('device', dict(dev=device.name, action='add')), shell=True)
- for qosclass in device.classes:
- call(self._render_config('class_add', dict(
+ try:
+ call(self._render_config('device', dict(dev=device.name, action='del')), shell=True)
+ except ExecutionError:
+ pass
+
+ try:
+ call(self._render_config('device', dict(dev=device.name, action='add')), shell=True)
+ except ExecutionError:
+ pass
+
+ for cls in device.classes.values():
+ try:
+ call(self._render_config('class_add', dict(
dev = device.name,
- cid = qosclass.cid,
- rate = qosclass.rate
- )
- ), shell=True)
- for host in qosclass.hosts:
- call(self._render_config('host_add', dict(
- dev = device.name,
- ip = host.ip,
- cid = qosclass.cid
+ cid = cls.cid,
+ rate = cls.rate
)
), shell=True)
+ except ExecutionError:
+ pass
+
+ for host in cls.hosts.values():
+ try:
+ call(self._render_config('host_add', dict(
+ dev = device.name,
+ ip = host.ip,
+ cid = cls.cid
+ )
+ ), shell=True)
+ except ExecutionError:
+ pass
def handle_timer(self):
self.refresh_devices()
-tc class add dev ${dev} classid 1:${id} htb rate ${rate}
+tc class add dev ${dev} classid 1:${cid} htb rate ${rate}kbps
-tc filter add dev ${dev} protocol ip u32 match ip src ${ip} flowid 1:{id}
+tc filter add dev ${dev} protocol ip u32 match ip src ${ip} flowid 1:${cid}
self.name = name
self.mac = mac
self.ppp = ppp
+ self.active = True
self.addrs = dict()
self.routes = list()
def as_tuple(self):
- return (self.name, self.mac, self.addrs)
+ return (self.name, self.mac, self.active, self.addrs)