diff options
| author | zsdc <taras@vyos.io> | 2023-06-27 23:04:14 +0300 | 
|---|---|---|
| committer | zsdc <taras@vyos.io> | 2023-06-27 23:04:14 +0300 | 
| commit | 0bf443acca2985a10ef26c1651992c185d4fd4fa (patch) | |
| tree | be968916659279131f15dfb024ac386181b5d854 | |
| parent | bc92f6d088105d2ede94ef7471fd987a0479faff (diff) | |
| download | vyos-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.py | 40 | ||||
| -rwxr-xr-x | src/conf_mode/vpp.py | 25 | 
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): | 
