]>
git.proxmox.com Git - ovs.git/blob - python/ovstest/util.py
db2ae989a2bd396534cda77b0d8cd0ec1599b3b5
1 # Copyright (c) 2011, 2012, 2017 Nicira, Inc.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at:
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
16 util module contains some helper function
31 import six
.moves
.xmlrpc_client
32 from six
.moves
import range
35 def str_ip(ip_address
):
37 Converts an IP address from binary format to a string.
39 (x1
, x2
, x3
, x4
) = struct
.unpack("BBBB", ip_address
)
40 return ("%u.%u.%u.%u") % (x1
, x2
, x3
, x4
)
43 def get_interface_mtu(iface
):
45 Returns MTU of the given interface.
47 s
= socket
.socket(socket
.AF_INET
, socket
.SOCK_DGRAM
)
48 indata
= iface
+ ('\0' * (32 - len(iface
)))
50 outdata
= fcntl
.ioctl(s
.fileno(), 0x8921, indata
) # socket.SIOCGIFMTU
51 mtu
= struct
.unpack("16si12x", outdata
)[1]
58 def get_interface(address
):
60 Finds first interface that has given address
63 s
= socket
.socket(socket
.AF_INET
, socket
.SOCK_DGRAM
)
64 names
= array
.array('B', '\0' * bytes
)
65 outbytes
= struct
.unpack('iL', fcntl
.ioctl(
68 struct
.pack('iL', bytes
, names
.buffer_info()[0])
70 namestr
= names
.tostring()
72 for i
in range(0, outbytes
, 40):
73 name
= namestr
[i
:i
+ 16].split('\0', 1)[0]
74 if address
== str_ip(namestr
[i
+ 20:i
+ 24]):
76 return None # did not find interface we were looking for
81 return os_info
[2] # return only the kernel version number
84 def start_process(args
):
86 p
= subprocess
.Popen(args
,
87 stdin
=subprocess
.PIPE
,
88 stdout
=subprocess
.PIPE
,
89 stderr
=subprocess
.PIPE
)
90 out
, err
= p
.communicate()
91 return (p
.returncode
, out
, err
)
92 except exceptions
.OSError:
93 return (-1, None, None)
96 def get_driver(iface
):
97 ret
, out
, _err
= start_process(["ethtool", "-i", iface
])
99 lines
= out
.splitlines()
100 driver
= "%s(%s)" % (lines
[0], lines
[1]) # driver name + version
106 def interface_up(iface
):
108 This function brings given iface up.
110 ret
, _out
, _err
= start_process(["ip", "link", "set", iface
, "up"])
114 def interface_assign_ip(iface
, ip_addr
, mask
):
116 This function adds an IP address to an interface. If mask is None
117 then a mask will be selected automatically. In case of success
118 this function returns 0.
120 interface_ip_op(iface
, ip_addr
, mask
, "add")
123 def interface_remove_ip(iface
, ip_addr
, mask
):
125 This function removes an IP address from an interface. If mask is
126 None then a mask will be selected automatically. In case of
127 success this function returns 0.
129 interface_ip_op(iface
, ip_addr
, mask
, "del")
132 def interface_ip_op(iface
, ip_addr
, mask
, op
):
134 arg
= "%s/%s" % (ip_addr
, mask
)
138 (x1
, x2
, x3
, x4
) = struct
.unpack("BBBB", socket
.inet_aton(ip_addr
))
140 arg
= "%s/8" % ip_addr
142 arg
= "%s/16" % ip_addr
144 arg
= "%s/24" % ip_addr
145 ret
, _out
, _err
= start_process(["ip", "addr", op
, arg
, "dev", iface
])
149 def interface_get_ip(iface
):
151 This function returns tuple - ip and mask that was assigned to the
154 args
= ["ip", "addr", "show", iface
]
155 ret
, out
, _err
= start_process(args
)
158 ip
= re
.search(r
'inet (\S+)/(\S+)', out
)
160 return (ip
.group(1), ip
.group(2))
165 def move_routes(iface1
, iface2
):
167 This function moves routes from iface1 to iface2.
169 args
= ["ip", "route", "show", "dev", iface1
]
170 ret
, out
, _err
= start_process(args
)
172 for route
in out
.splitlines():
173 args
= ["ip", "route", "replace", "dev", iface2
] + route
.split()
177 def get_interface_from_routing_decision(ip
):
179 This function returns the interface through which the given ip address
182 args
= ["ip", "route", "get", ip
]
183 ret
, out
, _err
= start_process(args
)
185 iface
= re
.search(r
'dev (\S+)', out
)
187 return iface
.group(1)
191 def rpc_client(ip
, port
):
192 return six
.moves
.xmlrpc_client
.Server("http://%s:%u/" % (ip
, port
),
196 def sigint_intercept():
198 Intercept SIGINT from child (the local ovs-test server process).
200 signal
.signal(signal
.SIGINT
, signal
.SIG_IGN
)
203 def start_local_server(port
):
205 This function spawns an ovs-test server that listens on specified port
206 and blocks till the spawned ovs-test server is ready to accept XML RPC
209 p
= subprocess
.Popen(["ovs-test", "-s", str(port
)],
210 stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
,
211 preexec_fn
=sigint_intercept
)
212 fcntl
.fcntl(p
.stdout
.fileno(), fcntl
.F_SETFL
,
213 fcntl
.fcntl(p
.stdout
.fileno(), fcntl
.F_GETFL
) | os
.O_NONBLOCK
)
215 while p
.poll() is None:
216 fd
= select
.select([p
.stdout
.fileno()], [], [])[0]
218 out
= p
.stdout
.readline()
219 if out
.startswith("Starting RPC server"):
221 if p
.poll() is not None:
222 raise RuntimeError("Couldn't start local instance of ovs-test server")
226 def get_datagram_sizes(mtu1
, mtu2
):
228 This function calculates all the "interesting" datagram sizes so that
229 we test both - receive and send side with different packets sizes.
231 s1
= set([8, mtu1
- 100, mtu1
- 28, mtu1
])
232 s2
= set([8, mtu2
- 100, mtu2
- 28, mtu2
])
233 return sorted(s1
.union(s2
))
236 def ip_from_cidr(string
):
238 This function removes the netmask (if present) from the given string and
239 returns the IP address.
241 token
= string
.split("/")
245 def bandwidth_to_string(bwidth
):
246 """Convert bandwidth from long to string and add units."""
247 bwidth
= bwidth
* 8 # Convert back to bits/second
248 if bwidth
>= 10000000:
249 return str(int(bwidth
/ 1000000)) + "Mbps"
251 return str(int(bwidth
/ 1000)) + "Kbps"
253 return str(int(bwidth
)) + "bps"