|
Packit Service |
0535c1 |
#
|
|
Packit Service |
0535c1 |
# Copyright (c) 2018-2020 Red Hat, Inc.
|
|
Packit Service |
0535c1 |
#
|
|
Packit Service |
0535c1 |
# This file is part of nmstate
|
|
Packit Service |
0535c1 |
#
|
|
Packit Service |
0535c1 |
# This program is free software: you can redistribute it and/or modify
|
|
Packit Service |
0535c1 |
# it under the terms of the GNU Lesser General Public License as published by
|
|
Packit Service |
0535c1 |
# the Free Software Foundation, either version 2.1 of the License, or
|
|
Packit Service |
0535c1 |
# (at your option) any later version.
|
|
Packit Service |
0535c1 |
#
|
|
Packit Service |
0535c1 |
# This program is distributed in the hope that it will be useful,
|
|
Packit Service |
0535c1 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
0535c1 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
0535c1 |
# GNU Lesser General Public License for more details.
|
|
Packit Service |
0535c1 |
#
|
|
Packit Service |
0535c1 |
# You should have received a copy of the GNU Lesser General Public License
|
|
Packit Service |
0535c1 |
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
Packit Service |
0535c1 |
#
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
from libnmstate.ethtool import minimal_ethtool
|
|
Packit Service |
0535c1 |
from libnmstate.nm import sriov
|
|
Packit Service |
0535c1 |
from libnmstate.schema import Ethernet
|
|
Packit Service |
0535c1 |
from libnmstate.schema import Interface
|
|
Packit Service |
0535c1 |
from .common import NM
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
ZEROED_MAC = "00:00:00:00:00:00"
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
class WiredSetting:
|
|
Packit Service |
0535c1 |
def __init__(self, state):
|
|
Packit Service |
0535c1 |
self.mtu = state.get(Interface.MTU)
|
|
Packit Service |
0535c1 |
self.mac = state.get(Interface.MAC)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
ethernet = state.get(Ethernet.CONFIG_SUBTREE, {})
|
|
Packit Service |
0535c1 |
self.speed = ethernet.get(Ethernet.SPEED)
|
|
Packit Service |
0535c1 |
self.duplex = ethernet.get(Ethernet.DUPLEX)
|
|
Packit Service |
0535c1 |
self.auto_negotiation = ethernet.get(Ethernet.AUTO_NEGOTIATION)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def __hash__(self):
|
|
Packit Service |
0535c1 |
return hash(self.__key())
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def __eq__(self, other):
|
|
Packit Service |
0535c1 |
return self is other or self.__key() == other.__key()
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def __ne__(self, other):
|
|
Packit Service |
0535c1 |
return not self.__eq__(other)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def __bool__(self):
|
|
Packit Service |
0535c1 |
return bool(
|
|
Packit Service |
0535c1 |
self.mac
|
|
Packit Service |
0535c1 |
or self.mtu
|
|
Packit Service |
0535c1 |
or self.speed
|
|
Packit Service |
0535c1 |
or self.duplex
|
|
Packit Service |
0535c1 |
or (self.auto_negotiation is not None)
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def __key(self):
|
|
Packit Service |
0535c1 |
return (
|
|
Packit Service |
0535c1 |
self.mtu,
|
|
Packit Service |
0535c1 |
self.mac,
|
|
Packit Service |
0535c1 |
self.speed,
|
|
Packit Service |
0535c1 |
self.duplex,
|
|
Packit Service |
0535c1 |
self.auto_negotiation,
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def create_setting(iface_state, base_con_profile):
|
|
Packit Service |
0535c1 |
setting = WiredSetting(iface_state)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
nm_wired_setting = None
|
|
Packit Service |
0535c1 |
if base_con_profile:
|
|
Packit Service |
0535c1 |
nm_wired_setting = base_con_profile.get_setting_wired()
|
|
Packit Service |
0535c1 |
if nm_wired_setting:
|
|
Packit Service |
0535c1 |
nm_wired_setting = nm_wired_setting.duplicate()
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
if not setting:
|
|
Packit Service |
0535c1 |
return nm_wired_setting
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
if not nm_wired_setting:
|
|
Packit Service |
0535c1 |
nm_wired_setting = NM.SettingWired.new()
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
if setting.mac:
|
|
Packit Service |
0535c1 |
nm_wired_setting.props.cloned_mac_address = setting.mac
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
if setting.mtu:
|
|
Packit Service |
0535c1 |
nm_wired_setting.props.mtu = setting.mtu
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
if setting.auto_negotiation:
|
|
Packit Service |
0535c1 |
nm_wired_setting.props.auto_negotiate = True
|
|
Packit Service |
0535c1 |
if not setting.speed and not setting.duplex:
|
|
Packit Service |
0535c1 |
nm_wired_setting.props.speed = 0
|
|
Packit Service |
0535c1 |
nm_wired_setting.props.duplex = None
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
elif not setting.speed:
|
|
Packit Service |
0535c1 |
ethtool_results = minimal_ethtool(str(iface_state[Interface.NAME]))
|
|
Packit Service |
0535c1 |
setting.speed = ethtool_results[Ethernet.SPEED]
|
|
Packit Service |
0535c1 |
elif not setting.duplex:
|
|
Packit Service |
0535c1 |
ethtool_results = minimal_ethtool(str(iface_state[Interface.NAME]))
|
|
Packit Service |
0535c1 |
setting.duplex = ethtool_results[Ethernet.DUPLEX]
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
elif setting.auto_negotiation is False:
|
|
Packit Service |
0535c1 |
nm_wired_setting.props.auto_negotiate = False
|
|
Packit Service |
0535c1 |
ethtool_results = minimal_ethtool(str(iface_state[Interface.NAME]))
|
|
Packit Service |
0535c1 |
if not setting.speed:
|
|
Packit Service |
0535c1 |
setting.speed = ethtool_results[Ethernet.SPEED]
|
|
Packit Service |
0535c1 |
if not setting.duplex:
|
|
Packit Service |
0535c1 |
setting.duplex = ethtool_results[Ethernet.DUPLEX]
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
if setting.speed:
|
|
Packit Service |
0535c1 |
nm_wired_setting.props.speed = setting.speed
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
if setting.duplex in [Ethernet.HALF_DUPLEX, Ethernet.FULL_DUPLEX]:
|
|
Packit Service |
0535c1 |
nm_wired_setting.props.duplex = setting.duplex
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
return nm_wired_setting
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def get_info(device):
|
|
Packit Service |
0535c1 |
"""
|
|
Packit Service |
0535c1 |
Provides the current active values for a device
|
|
Packit Service |
0535c1 |
"""
|
|
Packit Service |
0535c1 |
info = {}
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
iface = device.get_iface()
|
|
Packit Service |
0535c1 |
try:
|
|
Packit Service |
6a4bbd |
mtu = int(device.get_mtu())
|
|
Packit Service |
6a4bbd |
if mtu:
|
|
Packit Service |
6a4bbd |
info[Interface.MTU] = mtu
|
|
Packit Service |
0535c1 |
except AttributeError:
|
|
Packit Service |
0535c1 |
pass
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
mac = device.get_hw_address()
|
|
Packit Service |
0535c1 |
if not mac:
|
|
Packit Service |
0535c1 |
mac = _get_mac_address_from_sysfs(iface)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
# A device may not have a MAC or it may not yet be "realized" (zeroed mac).
|
|
Packit Service |
0535c1 |
if mac and mac != ZEROED_MAC:
|
|
Packit Service |
0535c1 |
info[Interface.MAC] = mac
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
if device.get_device_type() == NM.DeviceType.ETHERNET:
|
|
Packit Service |
0535c1 |
ethernet = _get_ethernet_info(device, iface)
|
|
Packit Service |
0535c1 |
if ethernet:
|
|
Packit Service |
0535c1 |
info[Ethernet.CONFIG_SUBTREE] = ethernet
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
return info
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def _get_mac_address_from_sysfs(ifname):
|
|
Packit Service |
0535c1 |
"""
|
|
Packit Service |
0535c1 |
Fetch the mac address of an interface from sysfs.
|
|
Packit Service |
0535c1 |
This is a workaround for https://bugzilla.redhat.com/1786937.
|
|
Packit Service |
0535c1 |
"""
|
|
Packit Service |
0535c1 |
mac = None
|
|
Packit Service |
0535c1 |
sysfs_path = f"/sys/class/net/{ifname}/address"
|
|
Packit Service |
0535c1 |
try:
|
|
Packit Service |
0535c1 |
with open(sysfs_path) as f:
|
|
Packit Service |
0535c1 |
mac = f.read().rstrip("\n").upper()
|
|
Packit Service |
0535c1 |
except FileNotFoundError:
|
|
Packit Service |
0535c1 |
pass
|
|
Packit Service |
0535c1 |
return mac
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def _get_ethernet_info(device, iface):
|
|
Packit Service |
0535c1 |
ethernet = {}
|
|
Packit Service |
0535c1 |
try:
|
|
Packit Service |
0535c1 |
speed = int(device.get_speed())
|
|
Packit Service |
0535c1 |
if speed > 0:
|
|
Packit Service |
0535c1 |
ethernet[Ethernet.SPEED] = speed
|
|
Packit Service |
0535c1 |
else:
|
|
Packit Service |
0535c1 |
return None
|
|
Packit Service |
0535c1 |
except AttributeError:
|
|
Packit Service |
0535c1 |
return None
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
ethtool_results = minimal_ethtool(iface)
|
|
Packit Service |
0535c1 |
auto_setting = ethtool_results[Ethernet.AUTO_NEGOTIATION]
|
|
Packit Service |
0535c1 |
if auto_setting is True:
|
|
Packit Service |
0535c1 |
ethernet[Ethernet.AUTO_NEGOTIATION] = True
|
|
Packit Service |
0535c1 |
elif auto_setting is False:
|
|
Packit Service |
0535c1 |
ethernet[Ethernet.AUTO_NEGOTIATION] = False
|
|
Packit Service |
0535c1 |
else:
|
|
Packit Service |
0535c1 |
return None
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
duplex_setting = ethtool_results[Ethernet.DUPLEX]
|
|
Packit Service |
0535c1 |
if duplex_setting in [Ethernet.HALF_DUPLEX, Ethernet.FULL_DUPLEX]:
|
|
Packit Service |
0535c1 |
ethernet[Ethernet.DUPLEX] = duplex_setting
|
|
Packit Service |
0535c1 |
else:
|
|
Packit Service |
0535c1 |
return None
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
sriov_info = sriov.get_info(device)
|
|
Packit Service |
0535c1 |
if sriov_info:
|
|
Packit Service |
0535c1 |
ethernet.update(sriov_info)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
return ethernet
|