|
Packit |
b9ca78 |
#
|
|
Packit |
b9ca78 |
# Copyright (c) 2018-2019 Red Hat, Inc.
|
|
Packit |
b9ca78 |
#
|
|
Packit |
b9ca78 |
# This file is part of nmstate
|
|
Packit |
b9ca78 |
#
|
|
Packit |
b9ca78 |
# This program is free software: you can redistribute it and/or modify
|
|
Packit |
b9ca78 |
# it under the terms of the GNU Lesser General Public License as published by
|
|
Packit |
b9ca78 |
# the Free Software Foundation, either version 2.1 of the License, or
|
|
Packit |
b9ca78 |
# (at your option) any later version.
|
|
Packit |
b9ca78 |
#
|
|
Packit |
b9ca78 |
# This program is distributed in the hope that it will be useful,
|
|
Packit |
b9ca78 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
b9ca78 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
b9ca78 |
# GNU Lesser General Public License for more details.
|
|
Packit |
b9ca78 |
#
|
|
Packit |
b9ca78 |
# You should have received a copy of the GNU Lesser General Public License
|
|
Packit |
b9ca78 |
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
Packit |
b9ca78 |
#
|
|
Packit |
b9ca78 |
""" Minimal wrapper around the SIOCETHTOOL IOCTL to provide data that Network
|
|
Packit |
b9ca78 |
Manager is not yet providing.
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
https://bugzilla.redhat.com/show_bug.cgi?id=1621188
|
|
Packit |
b9ca78 |
"""
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
import array
|
|
Packit |
b9ca78 |
import struct
|
|
Packit |
b9ca78 |
import fcntl
|
|
Packit |
b9ca78 |
import socket
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
ETHTOOL_GSET = 0x00000001 # Get settings
|
|
Packit |
b9ca78 |
SIOCETHTOOL = 0x8946
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
def minimal_ethtool(interface):
|
|
Packit |
b9ca78 |
"""
|
|
Packit |
b9ca78 |
Return dictionary with speed, duplex and auto-negotiation settings for the
|
|
Packit |
b9ca78 |
specified interface using the ETHTOOL_GSET command. The speed is returned n
|
|
Packit |
b9ca78 |
MBit/s, 0 means that the speed could not be determined. The duplex setting
|
|
Packit |
b9ca78 |
is 'unknown', 'full' or 'half. The auto-negotiation setting True or False
|
|
Packit |
b9ca78 |
or None if it could not be determined.
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
Based on:
|
|
Packit |
b9ca78 |
https://github.com/rlisagor/pynetlinux/blob/master/pynetlinux/ifconfig.py
|
|
Packit |
b9ca78 |
https://elixir.bootlin.com/linux/v4.19-rc1/source/include/uapi/linux/ethtool.h
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
:param interface str: Name of interface
|
|
Packit |
b9ca78 |
:returns dict: Dictionary with the keys speed, duplex, auto-negotiation
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
"""
|
|
Packit |
b9ca78 |
try:
|
|
Packit |
b9ca78 |
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
Packit |
b9ca78 |
sockfd = sock.fileno()
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
ecmd = array.array(
|
|
Packit |
b9ca78 |
"B", struct.pack("I39s", ETHTOOL_GSET, b"\x00" * 39)
|
|
Packit |
b9ca78 |
)
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
interface = interface.encode("utf-8")
|
|
Packit |
b9ca78 |
ifreq = struct.pack("16sP", interface, ecmd.buffer_info()[0])
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
fcntl.ioctl(sockfd, SIOCETHTOOL, ifreq)
|
|
Packit |
b9ca78 |
res = ecmd.tobytes()
|
|
Packit |
b9ca78 |
speed, duplex, auto = struct.unpack("12xHB3xB24x", res)
|
|
Packit |
b9ca78 |
except IOError:
|
|
Packit |
b9ca78 |
speed, duplex, auto = 65535, 255, 255
|
|
Packit |
b9ca78 |
finally:
|
|
Packit |
b9ca78 |
sock.close()
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
if speed == 65535:
|
|
Packit |
b9ca78 |
speed = 0
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
if duplex == 255:
|
|
Packit |
b9ca78 |
duplex = "unknown"
|
|
Packit |
b9ca78 |
else:
|
|
Packit |
b9ca78 |
duplex = "full" if bool(duplex) else "half"
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
if auto == 255:
|
|
Packit |
b9ca78 |
auto = None
|
|
Packit |
b9ca78 |
else:
|
|
Packit |
b9ca78 |
auto = bool(auto)
|
|
Packit |
b9ca78 |
|
|
Packit |
b9ca78 |
return {"speed": speed, "duplex": duplex, "auto-negotiation": auto}
|