blob: 90cb02210205c502156a8b7057772861595c5300 [file] [log] [blame]
Hariharasubramanian Rcd387972016-01-20 07:19:41 -06001#!/usr/bin/env python
2
Hariharasubramanian R308cffc2016-03-03 09:35:16 -06003from subprocess import call, Popen, PIPE
Hariharasubramanian Rcd387972016-01-20 07:19:41 -06004import sys
5import subprocess
6import dbus
7import string
Hariharasubramanian R308cffc2016-03-03 09:35:16 -06008import socket
9import re
Hariharasubramanian Rcd387972016-01-20 07:19:41 -060010import os
11import fcntl
12import glib
13import gobject
14import dbus.service
15import dbus.mainloop.glib
16
17DBUS_NAME = 'org.openbmc.NetworkManager'
18OBJ_NAME = '/org/openbmc/NetworkManager/Interface'
19
20network_providers = {
Adriana Kobylak88c733b2016-02-03 16:46:58 -060021 'networkd' : {
22 'bus_name' : 'org.freedesktop.network1',
23 'ip_object_name' : '/org/freedesktop/network1/network/default',
24 'hw_object_name' : '/org/freedesktop/network1/link/_31',
Hariharasubramanian R3a224e72016-02-10 12:32:08 -060025 'ip_if_name' : 'org.freedesktop.network1.Network',
26 'hw_if_name' : 'org.freedesktop.network1.Link',
Adriana Kobylak88c733b2016-02-03 16:46:58 -060027 'method' : 'org.freedesktop.network1.Network.SetAddr'
28 },
29 'NetworkManager' : {
30 'bus_name' : 'org.freedesktop.NetworkManager',
31 'ip_object_name' : '/org/freedesktop/NetworkManager',
32 'hw_object_name' : '/org/freedesktop/NetworkManager',
Hariharasubramanian R3a224e72016-02-10 12:32:08 -060033 'ip_if_name' : 'org.freedesktop.NetworkManager',
34 'hw_if_name' : 'org.freedesktop.NetworkManager',
Adriana Kobylak88c733b2016-02-03 16:46:58 -060035 'method' : 'org.freedesktop.NetworkManager' # FIXME:
36 },
Hariharasubramanian Rcd387972016-01-20 07:19:41 -060037}
38
39def getPrefixLen(mask):
Adriana Kobylak88c733b2016-02-03 16:46:58 -060040 prefixLen = sum([bin(int(x)).count('1') for x in mask.split('.')])
41 return prefixLen
Hariharasubramanian Rcd387972016-01-20 07:19:41 -060042
43class IfAddr ():
44 def __init__ (self, family, scope, flags, prefixlen, addr, gw):
45 self.family = family
46 self.scope = scope
47 self.flags = flags
48 self.prefixlen = prefixlen
49 self.addr = addr
50 self.gw = gw
51
52class NetMan (dbus.service.Object):
53 def __init__(self, bus, name):
54 self.bus = bus
55 self.name = name
56 dbus.service.Object.__init__(self,bus,name)
57
58 def setNetworkProvider(self, provider):
59 self.provider = provider
60
Hariharasubramanian R308cffc2016-03-03 09:35:16 -060061 def _isvaliddev(self, device):
62 devices = os.listdir ("/sys/class/net")
63 if not device in devices : return False
64 else: return True
Hariharasubramanian Rcd387972016-01-20 07:19:41 -060065
Hariharasubramanian R308cffc2016-03-03 09:35:16 -060066 def _ishwdev (self, device):
67 f = open ("/sys/class/net/"+device+"/type")
68 type = f.read()
69 return False if (int(type) == 772) else True
Hariharasubramanian Rcd387972016-01-20 07:19:41 -060070
Hariharasubramanian R308cffc2016-03-03 09:35:16 -060071 def _isvalidmask (self, mask):
72 for x in mask.split('.'):
73 try:
74 y = int(x)
75 except:
76 return False
77 if y > 255: return False
78 return mask.count('.') == 3
79
80 def _isvalidmac(self, mac):
81 macre = '([a-fA-F0-9]{2}[:|\-]?){6}'
82 if re.compile(macre).search(mac) : return True
83 else: return False
84
85 def _isvalidip(self, family, ipaddr):
86 if family == socket.AF_INET:
87 try:
88 socket.inet_pton(socket.AF_INET, ipaddr)
89 except AttributeError: # no inet_pton here, sorry
90 try:
91 socket.inet_aton(ipaddr)
92 except socket.error:
93 return False
94 return ipaddr.count('.') == 3
95 except socket.error: # not a valid address
96 return False
97
98 return True
99
100 elif family == socket.AF_INET6:
101 try:
102 socket.inet_pton(socket.AF_INET6, ipaddr)
103 except socket.error: # not a valid address
104 return False
105 return True
106
107 else: return False
Hariharasubramanian Rcd387972016-01-20 07:19:41 -0600108
109 def _getAddr (self, target, device):
110 netprov = network_providers [self.provider]
111 bus_name = netprov ['bus_name']
112
113 if (target == "ip"):
Hariharasubramanian R308cffc2016-03-03 09:35:16 -0600114 ipaddr = ""
115 defgw = ""
116 prefixlen = "0"
117
118 proc = subprocess.Popen(["ip", "addr", "show", "dev", device], stdout=PIPE)
119 procout = proc.communicate()
120 if procout:
121 ipout = procout[0].splitlines()[2].strip()
122 ipaddr,prefixlen = ipout.split ()[1].split("/")
123
124 proc = subprocess.Popen(["ip", "route", "show", "dev", device, "default", "0.0.0.0/0"], stdout=PIPE)
125 procout = proc.communicate()
126 if procout[0]:
127 ipout = procout[0].splitlines()[0].strip()
128 defgw = ipout.split ()[2]
129
130 return 2, int(prefixlen), ipaddr, defgw
Hariharasubramanian Rcd387972016-01-20 07:19:41 -0600131
132 if (target == "mac"):
Hariharasubramanian R308cffc2016-03-03 09:35:16 -0600133 proc = subprocess.Popen(["ip", "link", "show", "dev", device], stdout=PIPE)
134 ipout = proc.communicate()[0].splitlines()[1].strip()
135 mac = ipout.split ()[1]
Hariharasubramanian Rcd387972016-01-20 07:19:41 -0600136 return mac
137
Hariharasubramanian Rcd387972016-01-20 07:19:41 -0600138 @dbus.service.method(DBUS_NAME, "", "")
139 def test(self):
140 print("TEST")
141
Hariharasubramanian R3a224e72016-02-10 12:32:08 -0600142 @dbus.service.method(DBUS_NAME, "s", "x")
143 def EnableDHCP (self, device):
Hariharasubramanian R308cffc2016-03-03 09:35:16 -0600144 if not self._isvaliddev (device) : raise ValueError, "Invalid Device"
145
146 confFile = "/etc/systemd/network/00-bmc-" + device + ".network"
Hariharasubramanian R3a224e72016-02-10 12:32:08 -0600147
148 print("Making .network file...")
Hariharasubramanian R308cffc2016-03-03 09:35:16 -0600149 try:
150 networkconf = open (confFile, "w+")
151 except IOError:
152 raise IOError, "Failed to open " + confFile
153
Hariharasubramanian R3a224e72016-02-10 12:32:08 -0600154 networkconf.write ('[Match]'+ '\n')
155 networkconf.write ('Name=' + (device) + '\n')
156 networkconf.write ('[Network]' + '\n')
157 networkconf.write ('DHCP=yes')
158 networkconf.close ()
159
160 print("Restarting networkd service...")
Hariharasubramanian R308cffc2016-03-03 09:35:16 -0600161 rc = call(["ip", "addr", "flush", device])
162 rc = call(["systemctl", "restart", "systemd-networkd.service"])
163 return rc
Hariharasubramanian R3a224e72016-02-10 12:32:08 -0600164
Hariharasubramanian Rcd387972016-01-20 07:19:41 -0600165 @dbus.service.method(DBUS_NAME, "ssss", "x")
Hariharasubramanian R308cffc2016-03-03 09:35:16 -0600166 def SetAddress4 (self, device, ipaddr, netmask, gateway):
167 if not self._isvaliddev (device) : raise ValueError, "Invalid Device"
168 if not self._isvalidip (socket.AF_INET, ipaddr) : raise ValueError, "Malformed IP Address"
169 if not self._isvalidip (socket.AF_INET, gateway) : raise ValueError, "Malformed GW Address"
170 if not self._isvalidmask (netmask) : raise ValueError, "Invalid Mask"
171
Hariharasubramanian Rcd387972016-01-20 07:19:41 -0600172 prefixLen = getPrefixLen (netmask)
Hariharasubramanian R308cffc2016-03-03 09:35:16 -0600173 if prefixLen == 0: raise ValueError, "Invalid Mask"
174
175 confFile = "/etc/systemd/network/00-bmc-" + device + ".network"
Hariharasubramanian Rcd387972016-01-20 07:19:41 -0600176
177 print("Making .network file...")
Hariharasubramanian R308cffc2016-03-03 09:35:16 -0600178 try:
179 networkconf = open (confFile, "w+")
180 except IOError:
181 raise IOError, "Failed to open " + confFile
182
Hariharasubramanian Rcd387972016-01-20 07:19:41 -0600183 networkconf.write ('[Match]'+ '\n')
184 networkconf.write ('Name=' + (device) + '\n')
185 networkconf.write ('[Network]' + '\n')
186 networkconf.write ('Address=' + ipaddr + '/' + str(prefixLen) + '\n')
187 networkconf.write ('Gateway=' + gateway + '\n')
Chris Austenb13a3cd2016-02-01 18:18:21 -0600188 networkconf.close()
Hariharasubramanian Rcd387972016-01-20 07:19:41 -0600189
190 print("Restarting networkd service...")
Hariharasubramanian R308cffc2016-03-03 09:35:16 -0600191 rc = call(["ip", "addr", "flush", device])
192 rc = call(["systemctl", "restart", "systemd-networkd.service"])
193 return rc
Hariharasubramanian Rcd387972016-01-20 07:19:41 -0600194
Hariharasubramanian Rcc28a6f2016-04-29 12:25:12 -0500195 @dbus.service.method(DBUS_NAME, "s", "s")
196 def GetAddressType (self, device):
197 if not self._isvaliddev (device) : raise ValueError, "Invalid Device"
198
199 confFile = "/etc/systemd/network/00-bmc-" + device + ".network"
200 if not os.path.exists(confFile):
201 print "Config file (%s) not found !" % confFile
202 netprov = network_providers [self.provider]
203 bus_name = netprov ['bus_name']
204 obj_name = netprov ['ip_object_name']
205 o = self.bus.get_object(bus_name, obj_name, introspect=False)
206 i = dbus.Interface(o, 'org.freedesktop.DBus.Properties')
207 f = i.Get (netprov ['ip_if_name'], "SourcePath")
208 print "Using default networkd config file (%s)" % f
209 confFile = f
210
211 with open(confFile, "r") as f:
212 for line in f:
213 config = line.split ("=")
214 if (len (config) < 2) : continue
215 if config [0].upper() == "DHCP":
216 v = config[1].strip().upper()
217 if (v=="YES" or v=="IPV4" or v=="IPV6"):
218 return "DHCP"
219 return "STATIC"
220
Hariharasubramanian R308cffc2016-03-03 09:35:16 -0600221 #family, prefixlen, ip, defgw
222 @dbus.service.method(DBUS_NAME, "s", "iyss")
Hariharasubramanian Rcd387972016-01-20 07:19:41 -0600223 def GetAddress4 (self, device):
Hariharasubramanian R308cffc2016-03-03 09:35:16 -0600224 if not self._isvaliddev (device) : raise ValueError, "Invalid Device"
Hariharasubramanian Rcd387972016-01-20 07:19:41 -0600225 return self._getAddr ("ip", device)
226
227 @dbus.service.method(DBUS_NAME, "s", "s")
228 def GetHwAddress (self, device):
Hariharasubramanian R308cffc2016-03-03 09:35:16 -0600229 if not self._isvaliddev (device) : raise ValueError, "Invalid Device"
Hariharasubramanian Rcd387972016-01-20 07:19:41 -0600230 return self._getAddr ("mac", device)
231
Hariharasubramanian R308cffc2016-03-03 09:35:16 -0600232 @dbus.service.method(DBUS_NAME, "ss", "i")
233 def SetHwAddress (self, device, mac):
234 if not self._isvaliddev (device) : raise ValueError, "Invalid Device"
235 if not self._ishwdev (device) : raise ValueError, "Not a Hardware Device"
236 if not self._isvalidmac (mac) : raise ValueError, "Malformed MAC address"
237
Adriana Kobylak88c733b2016-02-03 16:46:58 -0600238 rc = subprocess.call(["fw_setenv", "ethaddr", mac])
Hariharasubramanian R308cffc2016-03-03 09:35:16 -0600239
240 print("Restarting networkd service...")
241 rc = call(["ip", "link", "set", "dev", device, "down"])
242 rc = call(["ip", "link", "set", "dev", device, "address", mac])
243 rc = call(["ip", "link", "set", "dev", device, "up"])
244
245 rc = call(["systemctl", "restart", "systemd-networkd.service"])
Adriana Kobylak88c733b2016-02-03 16:46:58 -0600246 return rc
247
vishwa5c912c82016-03-24 07:59:28 -0500248 #string of nameservers
249 @dbus.service.method(DBUS_NAME,"s", "s")
250 def SetNameServers (self, nameservers):
251 dns_entry = nameservers.split()
252 fail_msg = ''
253 dhcp_auto = False
254 file_opened = False
255 if len(dns_entry) > 0:
256 for dns in dns_entry:
257 if not self._isvalidip (socket.AF_INET, dns):
258 if dns == "DHCP_AUTO=":
259 #This DNS is supplied by DHCP.
260 dhcp_auto = True
261 else:
262 print "Malformed DNS Address [" + dns + "]"
263 fail_msg = fail_msg + '[' + dns + ']'
264 else:
265 #Only over write on a first valid input
266 if file_opened == False:
267 resolv_conf = open("/etc/resolv.conf",'w')
268 file_opened = True
269 if dhcp_auto == True:
270 resolv_conf.write("### Generated automatically via DHCP ###\n")
271 else:
272 resolv_conf.write("### Generated manually via dbus settings ###\n")
273 dns_ip = 'nameserver ' + dns + '\n'
274 resolv_conf.write(dns_ip)
275 if file_opened == True:
276 resolv_conf.close()
277 else:
278 raise ValueError, "Invalid DNS entry"
279 if len(fail_msg) > 0:
280 return 'Failures encountered processing' + fail_msg
281 else:
282 return "DNS entries updated Successfully"
283
Hariharasubramanian Rcd387972016-01-20 07:19:41 -0600284def main():
285 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
286 bus = dbus.SystemBus()
287 name = dbus.service.BusName(DBUS_NAME, bus)
288 obj = NetMan (bus, OBJ_NAME)
289 obj.setNetworkProvider ("networkd")
290 mainloop = gobject.MainLoop()
291 print("Started")
292 mainloop.run()
293
294if __name__ == '__main__':
Adriana Kobylake150bfd2016-02-01 21:47:34 -0600295 sys.exit(main())