]>
git.proxmox.com Git - mirror_ifupdown2.git/blob - addons/dhcp.py
3 # Copyright 2014 Cumulus Networks, Inc. All rights reserved.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
9 from ipaddr
import IPNetwork
11 from ifupdown
.iface
import *
12 import ifupdown
.policymanager
as policymanager
13 from ifupdownaddons
.modulebase
import moduleBase
14 from ifupdownaddons
.dhclient
import dhclient
15 from ifupdownaddons
.iproute2
import iproute2
16 import ifupdown
.ifupdownflags
as ifupdownflags
17 from ifupdown
.utils
import utils
19 from ifupdown
.netlink
import netlink
20 except ImportError, e
:
21 raise ImportError (str(e
) + "- required module not found")
23 class dhcp(moduleBase
):
24 """ ifupdown2 addon module to configure dhcp on interface """
26 def __init__(self
, *args
, **kargs
):
27 moduleBase
.__init
__(self
, *args
, **kargs
)
28 self
.dhclientcmd
= dhclient(**kargs
)
31 def syntax_check(self
, ifaceobj
, ifaceobj_getfunc
):
32 return self
.is_dhcp_allowed_on(ifaceobj
, syntax_check
=True)
34 def is_dhcp_allowed_on(self
, ifaceobj
, syntax_check
):
35 if ifaceobj
.addr_method
and 'dhcp' in ifaceobj
.addr_method
:
36 return utils
.is_addr_ip_allowed_on(ifaceobj
, syntax_check
=True)
39 def _up(self
, ifaceobj
):
40 # if dhclient is already running do not stop and start it
41 if self
.dhclientcmd
.is_running(ifaceobj
.name
) or \
42 self
.dhclientcmd
.is_running6(ifaceobj
.name
):
43 self
.logger
.info('dhclient already running on %s. Not restarting.' % \
47 dhclient_cmd_prefix
= None
48 dhcp_wait
= policymanager
.policymanager_api
.get_attr_default(
49 module_name
=self
.__class
__.__name
__, attr
='dhcp-wait')
50 wait
= not str(dhcp_wait
).lower() == "no"
51 vrf
= ifaceobj
.get_attr_value_first('vrf')
52 if (vrf
and self
.vrf_exec_cmd_prefix
and
53 self
.ipcmd
.link_exists(vrf
)):
54 dhclient_cmd_prefix
= '%s %s' %(self
.vrf_exec_cmd_prefix
, vrf
)
56 if 'inet' in ifaceobj
.addr_family
:
57 # First release any existing dhclient processes
59 if not ifupdownflags
.flags
.PERFMODE
:
60 self
.dhclientcmd
.stop(ifaceobj
.name
)
63 self
.dhclientcmd
.start(ifaceobj
.name
, wait
=wait
,
64 cmd_prefix
=dhclient_cmd_prefix
)
65 if 'inet6' in ifaceobj
.addr_family
:
66 accept_ra
= ifaceobj
.get_attr_value_first('accept_ra')
69 self
.sysctl_set('net.ipv6.conf.%s' %ifaceobj
.name
+
70 '.accept_ra', accept_ra
)
71 autoconf
= ifaceobj
.get_attr_value_first('autoconf')
74 self
.sysctl_set('net.ipv6.conf.%s' %ifaceobj
.name
+
75 '.autoconf', autoconf
)
77 self
.dhclientcmd
.stop6(ifaceobj
.name
)
80 #add delay before starting IPv6 dhclient to
81 #make sure the configured interface/link is up.
86 addr_output
= utils
.exec_command('ip -6 addr show %s'
88 r
= re
.search('inet6 .* scope link', addr_output
)
90 self
.dhclientcmd
.start6(ifaceobj
.name
,
92 cmd_prefix
=dhclient_cmd_prefix
)
98 self
.log_error(str(e
), ifaceobj
)
100 def _down(self
, ifaceobj
):
101 dhclient_cmd_prefix
= None
102 vrf
= ifaceobj
.get_attr_value_first('vrf')
103 if (vrf
and self
.vrf_exec_cmd_prefix
and
104 self
.ipcmd
.link_exists(vrf
)):
105 dhclient_cmd_prefix
= '%s %s' %(self
.vrf_exec_cmd_prefix
, vrf
)
106 if 'inet6' in ifaceobj
.addr_family
:
107 self
.dhclientcmd
.release6(ifaceobj
.name
, dhclient_cmd_prefix
)
108 if 'inet' in ifaceobj
.addr_family
:
109 self
.dhclientcmd
.release(ifaceobj
.name
, dhclient_cmd_prefix
)
110 self
.ipcmd
.link_down(ifaceobj
.name
)
112 def _query_check(self
, ifaceobj
, ifaceobjcurr
):
113 status
= ifaceStatus
.SUCCESS
116 dhcp_v4
= self
.dhclientcmd
.is_running(ifaceobjcurr
.name
)
117 dhcp_v6
= self
.dhclientcmd
.is_running6(ifaceobjcurr
.name
)
121 if 'inet' not in ifaceobj
.addr_family
and not dhcp_v6
:
122 status
= ifaceStatus
.ERROR
123 ifaceobjcurr
.addr_method
= 'dhcp'
126 if 'inet6' not in ifaceobj
.addr_family
and not dhcp_v4
:
127 status
= ifaceStatus
.ERROR
128 ifaceobjcurr
.addr_method
= 'dhcp'
129 ifaceobjcurr
.addr_family
= ifaceobj
.addr_family
131 ifaceobjcurr
.addr_family
= []
132 status
= ifaceStatus
.ERROR
133 ifaceobjcurr
.status
= status
135 def _query_running(self
, ifaceobjrunning
):
136 if not self
.ipcmd
.link_exists(ifaceobjrunning
.name
):
138 if self
.dhclientcmd
.is_running(ifaceobjrunning
.name
):
139 ifaceobjrunning
.addr_family
.append('inet')
140 ifaceobjrunning
.addr_method
= 'dhcp'
141 if self
.dhclientcmd
.is_running6(ifaceobjrunning
.name
):
142 ifaceobjrunning
.addr_family
.append('inet6')
143 ifaceobjrunning
.addr_method
= 'dhcp6'
145 _run_ops
= {'up' : _up
,
148 'query-checkcurr' : _query_check
,
149 'query-running' : _query_running
}
152 """ returns list of ops supported by this module """
153 return self
._run
_ops
.keys()
155 def _init_command_handlers(self
):
157 self
.ipcmd
= iproute2()
159 def run(self
, ifaceobj
, operation
, query_ifaceobj
=None, **extra_args
):
160 """ run dhcp configuration on the interface object passed as argument
163 **ifaceobj** (object): iface object
165 **operation** (str): any of 'up', 'down', 'query-checkcurr',
169 **query_ifaceobj** (object): query check ifaceobject. This is only
170 valid when op is 'query-checkcurr'. It is an object same as
171 ifaceobj, but contains running attribute values and its config
172 status. The modules can use it to return queried running state
173 of interfaces. status is success if the running state is same
174 as user required state in ifaceobj. error otherwise.
176 op_handler
= self
._run
_ops
.get(operation
)
180 if (operation
!= 'query-running' and
181 (ifaceobj
.addr_method
!= 'dhcp' and
182 ifaceobj
.addr_method
!= 'dhcp6')):
186 if not self
.is_dhcp_allowed_on(ifaceobj
, syntax_check
=False):
188 self
._init
_command
_handlers
()
189 if operation
== 'query-checkcurr':
190 op_handler(self
, ifaceobj
, query_ifaceobj
)
192 op_handler(self
, ifaceobj
)