Enable PTP support for Link Aggregation

The Linux bonding driver aggregate multiple NICs into a single bonded
interface of two or more NIC slaves. This bonded interface has no
PTP hardware clock associated with it and cannot be used by the
LinuxPTP for clock synchronization. Need to derive all the LAG slaves
from the bonded interface and feed them to the LinuxPTP daemon instead
of the bonded interface. VLAN interface names should be cleared from
VLAN numbers as well in order for PTP to work.

Change-Id: I022e2d74e6459825129107881dd585bb2a13f953
Closes-bug: 1828017
Signed-off-by: Alex Kozyrev <alex.kozyrev@windriver.com>
This commit is contained in:
Alex Kozyrev
2019-05-14 16:21:21 -04:00
parent 345ec89902
commit 762fc1b5c9
6 changed files with 51 additions and 16 deletions

View File

@@ -505,8 +505,8 @@ def get_lower_interface_os_ifname(context, iface):
def get_interface_os_ifname(context, iface):
"""
Determine the interface name used in the linux kernel for the given
interface. Ethernet interfaces uses the original linux device name while
AE devices can use the user-defined named. VLAN interface must derive
interface. Ethernet interfaces uses the original linux device name while
AE devices can use the user-defined named. VLAN interface must derive
their names based on their lower interface name.
"""
if '_os_ifname' in iface: # check cached result
@@ -524,6 +524,28 @@ def get_interface_os_ifname(context, iface):
return iface['_os_ifname']
def get_interface_devices(context, iface, devices=None):
"""
Determine all the interface devices used in the linux kernel for the given
interface name. Ethernet interfaces uses the original linux device while AE
and VLAN interfaces use all the slave devices. Virtual interfaces use a name.
"""
if devices is None:
devices = []
if iface['iftype'] == constants.INTERFACE_TYPE_ETHERNET:
devices.append(get_interface_port_name(context, iface))
elif iface['iftype'] == constants.INTERFACE_TYPE_VIRTUAL:
devices.append(iface['ifname'])
elif iface['iftype'] == constants.INTERFACE_TYPE_VLAN \
or iface['iftype'] == constants.INTERFACE_TYPE_AE:
slaves = get_interface_slaves(context, iface)
for slave in slaves:
get_interface_devices(context, slave, devices)
return devices
def get_interface_routes(context, iface):
"""
Determine the list of routes that are applicable to a given interface (if
@@ -781,16 +803,16 @@ def get_primary_bond_interface(context, iface):
"""
Return the slave interface with the lowest MAC address
"""
slaves = get_bond_interface_slaves(context, iface)
slaves = get_interface_slaves(context, iface)
sorted_slaves = sorted(slaves, key=slave_sort_key)
primary_iface = sorted_slaves[0]
return primary_iface
def get_bond_interface_slaves(context, iface):
def get_interface_slaves(context, iface):
"""
Return the slave interface objects for the corresponding
bond interface
bond or vlan interface.
"""
slaves = iface['uses']
ifaces = []

View File

@@ -181,6 +181,8 @@ class NetworkingPuppet(base.BasePuppet):
if network_interface:
interface_name = interface.get_interface_os_ifname(
self.context, network_interface)
interface_devices = interface.get_interface_devices(
self.context, network_interface)
network_id = interface.find_network_id_by_networktype(
self.context, networktype)
# Convert the dash to underscore because puppet parameters cannot
@@ -189,6 +191,8 @@ class NetworkingPuppet(base.BasePuppet):
config.update({
'platform::network::%s::params::interface_name' % networktype:
interface_name,
'platform::network::%s::params::interface_devices' % networktype:
interface_devices,
'platform::network::%s::params::mtu' % networktype:
network_interface.imtu
})

View File

@@ -76,7 +76,7 @@ class OVSPuppet(base.BasePuppet):
ovs_flows.update({port['name']: flow})
if iface['iftype'] == constants.INTERFACE_TYPE_AE:
slaves = interface.get_bond_interface_slaves(
slaves = interface.get_interface_slaves(
self.context, iface)
for member, slave in enumerate(slaves):
ovs_ifname = port['interfaces'][member]['name']