summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzsdc <taras@vyos.io>2023-06-27 23:04:14 +0300
committerzsdc <taras@vyos.io>2023-06-27 23:04:14 +0300
commit0bf443acca2985a10ef26c1651992c185d4fd4fa (patch)
treebe968916659279131f15dfb024ac386181b5d854
parentbc92f6d088105d2ede94ef7471fd987a0479faff (diff)
downloadvyos-1x-0bf443acca2985a10ef26c1651992c185d4fd4fa.tar.gz
vyos-1x-0bf443acca2985a10ef26c1651992c185d4fd4fa.zip
VPP: T1797: Improved PCI address search
Use info from both ethtool and VPP to find PCI address for an interface.
-rw-r--r--python/vyos/vpp.py40
-rwxr-xr-xsrc/conf_mode/vpp.py25
2 files changed, 57 insertions, 8 deletions
diff --git a/python/vyos/vpp.py b/python/vyos/vpp.py
index 9e9471879..d60ecc1b3 100644
--- a/python/vyos/vpp.py
+++ b/python/vyos/vpp.py
@@ -13,6 +13,8 @@
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
+from re import search as re_search, MULTILINE as re_M
+
from vpp_papi import VPPApiClient
@@ -27,17 +29,29 @@ class VPPControl:
self.vpp_api_client.connect('vpp-vyos')
def __del__(self) -> None:
+ """Disconnect from VPP API (destructor)
+ """
+ self.disconnect()
+
+ def disconnect(self) -> None:
"""Disconnect from VPP API
"""
self.vpp_api_client.disconnect()
- def cli_cmd(self, command: str) -> None:
+ def cli_cmd(self, command: str, return_output: bool = False) -> str:
"""Send raw CLI command
Args:
command (str): command to send
+ return_output (bool, optional): Return command output. Defaults to False.
+
+ Returns:
+ str: output of the command, only if it was successful
"""
- self.vpp_api_client.api.cli_inband(cmd=command)
+ cli_answer = self.vpp_api_client.api.cli_inband(cmd=command)
+ if return_output and cli_answer.retval == 0:
+ return cli_answer.reply
+ return ''
def get_mac(self, ifname: str) -> str:
"""Find MAC address by interface name in VPP
@@ -112,3 +126,25 @@ class VPPControl:
iface_index = self.get_sw_if_index(iface_name)
self.vpp_api_client.api.sw_interface_set_rx_mode(
sw_if_index=iface_index, mode=modes_dict[rx_mode])
+
+ def get_pci_addr(self, ifname: str) -> str:
+ """Find PCI address of interface by interface name in VPP
+
+ Args:
+ ifname (str): interface name inside VPP
+
+ Returns:
+ str: PCI address
+ """
+ hw_info = self.cli_cmd(f'show hardware-interfaces {ifname}',
+ return_output=True)
+
+ regex_filter = r'^\s+pci: device (?P<device>\w+:\w+) subsystem (?P<subsystem>\w+:\w+) address (?P<address>\w+:\w+:\w+\.\w+) numa (?P<numa>\w+)$'
+ re_obj = re_search(regex_filter, hw_info, re_M)
+
+ # return empty string if no interface or no PCI info was found
+ if not hw_info or not re_obj:
+ return ''
+
+ address = re_obj.groupdict().get('address', '')
+ return address
diff --git a/src/conf_mode/vpp.py b/src/conf_mode/vpp.py
index d541e52ba..54ea54852 100755
--- a/src/conf_mode/vpp.py
+++ b/src/conf_mode/vpp.py
@@ -16,6 +16,7 @@
from pathlib import Path
+from re import search as re_search, MULTILINE as re_M
from vyos.config import Config
from vyos.configdict import dict_merge
@@ -38,14 +39,26 @@ service_conf = Path(f'/run/vpp/{service_name}.conf')
systemd_override = '/run/systemd/system/vpp.service.d/10-override.conf'
-def _get_pci_address_by_interface(iface):
+def _get_pci_address_by_interface(iface) -> str:
from vyos.util import rc_cmd
rc, out = rc_cmd(f'ethtool -i {iface}')
- if rc == 0:
- output_lines = out.split('\n')
- for line in output_lines:
- if 'bus-info' in line:
- return line.split(None, 1)[1].strip()
+ # if ethtool command was successful
+ if rc == 0 and out:
+ regex_filter = r'^bus-info: (?P<address>\w+:\w+:\w+\.\w+)$'
+ re_obj = re_search(regex_filter, out, re_M)
+ # if bus-info with PCI address found
+ if re_obj:
+ address = re_obj.groupdict().get('address', '')
+ return address
+ # use VPP - maybe interface already attached to it
+ vpp_control = VPPControl()
+ pci_addr = vpp_control.get_pci_addr(iface)
+ vpp_control.disconnect()
+ if pci_addr:
+ return pci_addr
+ # return empty string if address was not found
+ return ''
+
def get_config(config=None):