blob: 377833d850c9c0e2ecd070503649218b2dec06b5 [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 R308cffc2016-03-03 09:35:16 -0600195 #family, prefixlen, ip, defgw
196 @dbus.service.method(DBUS_NAME, "s", "iyss")
Hariharasubramanian Rcd387972016-01-20 07:19:41 -0600197 def GetAddress4 (self, device):
Hariharasubramanian R308cffc2016-03-03 09:35:16 -0600198 if not self._isvaliddev (device) : raise ValueError, "Invalid Device"
Hariharasubramanian Rcd387972016-01-20 07:19:41 -0600199 return self._getAddr ("ip", device)
200
201 @dbus.service.method(DBUS_NAME, "s", "s")
202 def GetHwAddress (self, device):
Hariharasubramanian R308cffc2016-03-03 09:35:16 -0600203 if not self._isvaliddev (device) : raise ValueError, "Invalid Device"
Hariharasubramanian Rcd387972016-01-20 07:19:41 -0600204 return self._getAddr ("mac", device)
205
Hariharasubramanian R308cffc2016-03-03 09:35:16 -0600206 @dbus.service.method(DBUS_NAME, "ss", "i")
207 def SetHwAddress (self, device, mac):
208 if not self._isvaliddev (device) : raise ValueError, "Invalid Device"
209 if not self._ishwdev (device) : raise ValueError, "Not a Hardware Device"
210 if not self._isvalidmac (mac) : raise ValueError, "Malformed MAC address"
211
Adriana Kobylak88c733b2016-02-03 16:46:58 -0600212 rc = subprocess.call(["fw_setenv", "ethaddr", mac])
Hariharasubramanian R308cffc2016-03-03 09:35:16 -0600213
214 print("Restarting networkd service...")
215 rc = call(["ip", "link", "set", "dev", device, "down"])
216 rc = call(["ip", "link", "set", "dev", device, "address", mac])
217 rc = call(["ip", "link", "set", "dev", device, "up"])
218
219 rc = call(["systemctl", "restart", "systemd-networkd.service"])
Adriana Kobylak88c733b2016-02-03 16:46:58 -0600220 return rc
221
Hariharasubramanian Rcd387972016-01-20 07:19:41 -0600222def main():
223 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
224 bus = dbus.SystemBus()
225 name = dbus.service.BusName(DBUS_NAME, bus)
226 obj = NetMan (bus, OBJ_NAME)
227 obj.setNetworkProvider ("networkd")
228 mainloop = gobject.MainLoop()
229 print("Started")
230 mainloop.run()
231
232if __name__ == '__main__':
Adriana Kobylake150bfd2016-02-01 21:47:34 -0600233 sys.exit(main())