]>
git.proxmox.com Git - mirror_ifupdown2.git/blob - ifupdown2/addons/dhcp.py
3 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
11 import ifupdown2
.ifupdown
.policymanager
as policymanager
12 import ifupdown2
.ifupdown
.ifupdownflags
as ifupdownflags
14 from ifupdown2
.ifupdown
.iface
import *
15 from ifupdown2
.ifupdown
.utils
import utils
17 from ifupdown2
.ifupdownaddons
.dhclient
import dhclient
18 from ifupdown2
.ifupdownaddons
.LinkUtils
import LinkUtils
19 from ifupdown2
.ifupdownaddons
.modulebase
import moduleBase
21 import ifupdown
.policymanager
as policymanager
22 import ifupdown
.ifupdownflags
as ifupdownflags
24 from ifupdown
.iface
import *
25 from ifupdown
.utils
import utils
27 from ifupdownaddons
.dhclient
import dhclient
28 from ifupdownaddons
.LinkUtils
import LinkUtils
29 from ifupdownaddons
.modulebase
import moduleBase
32 class dhcp(moduleBase
):
33 """ ifupdown2 addon module to configure dhcp on interface """
35 def __init__(self
, *args
, **kargs
):
36 moduleBase
.__init
__(self
, *args
, **kargs
)
37 self
.dhclientcmd
= dhclient(**kargs
)
40 def syntax_check(self
, ifaceobj
, ifaceobj_getfunc
):
41 return self
.is_dhcp_allowed_on(ifaceobj
, syntax_check
=True)
43 def is_dhcp_allowed_on(self
, ifaceobj
, syntax_check
):
44 if ifaceobj
.addr_method
and 'dhcp' in ifaceobj
.addr_method
:
45 return utils
.is_addr_ip_allowed_on(ifaceobj
, syntax_check
=True)
48 def _up(self
, ifaceobj
):
49 # if dhclient is already running do not stop and start it
50 dhclient4_running
= self
.dhclientcmd
.is_running(ifaceobj
.name
)
51 dhclient6_running
= self
.dhclientcmd
.is_running6(ifaceobj
.name
)
53 # today if we have an interface with both inet and inet6, if we
54 # remove the inet or inet6 or both then execute ifreload, we need
55 # to release/kill the appropriate dhclient(4/6) if they are running
56 self
._down
_stale
_dhcp
_config
(ifaceobj
, 'inet', dhclient4_running
)
57 self
._down
_stale
_dhcp
_config
(ifaceobj
, 'inet6', dhclient6_running
)
60 dhclient_cmd_prefix
= None
61 dhcp_wait
= policymanager
.policymanager_api
.get_attr_default(
62 module_name
=self
.__class
__.__name
__, attr
='dhcp-wait')
63 wait
= not str(dhcp_wait
).lower() == "no"
64 vrf
= ifaceobj
.get_attr_value_first('vrf')
65 if (vrf
and self
.vrf_exec_cmd_prefix
and
66 self
.ipcmd
.link_exists(vrf
)):
67 dhclient_cmd_prefix
= '%s %s' %(self
.vrf_exec_cmd_prefix
, vrf
)
69 if 'inet' in ifaceobj
.addr_family
:
71 self
.logger
.info('dhclient4 already running on %s. '
72 'Not restarting.' % ifaceobj
.name
)
74 # First release any existing dhclient processes
76 if not ifupdownflags
.flags
.PERFMODE
:
77 self
.dhclientcmd
.stop(ifaceobj
.name
)
80 self
.dhclientcmd
.start(ifaceobj
.name
, wait
=wait
,
81 cmd_prefix
=dhclient_cmd_prefix
)
82 if 'inet6' in ifaceobj
.addr_family
:
84 self
.logger
.info('dhclient6 already running on %s. '
85 'Not restarting.' % ifaceobj
.name
)
87 accept_ra
= ifaceobj
.get_attr_value_first('accept_ra')
90 self
.sysctl_set('net.ipv6.conf.%s' %ifaceobj
.name
+
91 '.accept_ra', accept_ra
)
92 autoconf
= ifaceobj
.get_attr_value_first('autoconf')
95 self
.sysctl_set('net.ipv6.conf.%s' %ifaceobj
.name
+
96 '.autoconf', autoconf
)
98 self
.dhclientcmd
.stop6(ifaceobj
.name
)
101 #add delay before starting IPv6 dhclient to
102 #make sure the configured interface/link is up.
107 addr_output
= utils
.exec_command('%s -6 addr show %s'
108 %(utils
.ip_cmd
, ifaceobj
.name
))
109 r
= re
.search('inet6 .* scope link', addr_output
)
111 self
.dhclientcmd
.start6(ifaceobj
.name
,
113 cmd_prefix
=dhclient_cmd_prefix
)
118 self
.log_error(str(e
), ifaceobj
)
120 def _down_stale_dhcp_config(self
, ifaceobj
, family
, dhclientX_running
):
121 addr_family
= ifaceobj
.addr_family
123 if not family
in ifaceobj
.addr_family
and dhclientX_running
:
124 ifaceobj
.addr_family
= [family
]
125 self
._dhcp
_down
(ifaceobj
)
129 ifaceobj
.addr_family
= addr_family
131 def _dhcp_down(self
, ifaceobj
):
132 dhclient_cmd_prefix
= None
133 vrf
= ifaceobj
.get_attr_value_first('vrf')
134 if (vrf
and self
.vrf_exec_cmd_prefix
and
135 self
.ipcmd
.link_exists(vrf
)):
136 dhclient_cmd_prefix
= '%s %s' %(self
.vrf_exec_cmd_prefix
, vrf
)
137 if 'inet6' in ifaceobj
.addr_family
:
138 self
.dhclientcmd
.release6(ifaceobj
.name
, dhclient_cmd_prefix
)
139 if 'inet' in ifaceobj
.addr_family
:
140 self
.dhclientcmd
.release(ifaceobj
.name
, dhclient_cmd_prefix
)
142 def _down(self
, ifaceobj
):
143 self
._dhcp
_down
(ifaceobj
)
144 self
.ipcmd
.link_down(ifaceobj
.name
)
146 def _query_check(self
, ifaceobj
, ifaceobjcurr
):
147 status
= ifaceStatus
.SUCCESS
150 dhcp_v4
= self
.dhclientcmd
.is_running(ifaceobjcurr
.name
)
151 dhcp_v6
= self
.dhclientcmd
.is_running6(ifaceobjcurr
.name
)
155 if 'inet' not in ifaceobj
.addr_family
and not dhcp_v6
:
156 status
= ifaceStatus
.ERROR
157 ifaceobjcurr
.addr_method
= 'dhcp'
160 if 'inet6' not in ifaceobj
.addr_family
and not dhcp_v4
:
161 status
= ifaceStatus
.ERROR
162 ifaceobjcurr
.addr_method
= 'dhcp'
163 ifaceobjcurr
.addr_family
= ifaceobj
.addr_family
165 ifaceobjcurr
.addr_family
= []
166 status
= ifaceStatus
.ERROR
167 ifaceobjcurr
.status
= status
169 def _query_running(self
, ifaceobjrunning
):
170 if not self
.ipcmd
.link_exists(ifaceobjrunning
.name
):
172 if self
.dhclientcmd
.is_running(ifaceobjrunning
.name
):
173 ifaceobjrunning
.addr_family
.append('inet')
174 ifaceobjrunning
.addr_method
= 'dhcp'
175 if self
.dhclientcmd
.is_running6(ifaceobjrunning
.name
):
176 ifaceobjrunning
.addr_family
.append('inet6')
177 ifaceobjrunning
.addr_method
= 'dhcp6'
179 _run_ops
= {'up' : _up
,
182 'query-checkcurr' : _query_check
,
183 'query-running' : _query_running
}
186 """ returns list of ops supported by this module """
187 return self
._run
_ops
.keys()
189 def _init_command_handlers(self
):
191 self
.ipcmd
= LinkUtils()
193 def run(self
, ifaceobj
, operation
, query_ifaceobj
=None, **extra_args
):
194 """ run dhcp configuration on the interface object passed as argument
197 **ifaceobj** (object): iface object
199 **operation** (str): any of 'up', 'down', 'query-checkcurr',
203 **query_ifaceobj** (object): query check ifaceobject. This is only
204 valid when op is 'query-checkcurr'. It is an object same as
205 ifaceobj, but contains running attribute values and its config
206 status. The modules can use it to return queried running state
207 of interfaces. status is success if the running state is same
208 as user required state in ifaceobj. error otherwise.
210 op_handler
= self
._run
_ops
.get(operation
)
214 if (operation
!= 'query-running' and
215 (ifaceobj
.addr_method
!= 'dhcp' and
216 ifaceobj
.addr_method
!= 'dhcp6')):
220 if not self
.is_dhcp_allowed_on(ifaceobj
, syntax_check
=False):
222 self
._init
_command
_handlers
()
223 if operation
== 'query-checkcurr':
224 op_handler(self
, ifaceobj
, query_ifaceobj
)
226 op_handler(self
, ifaceobj
)