diff options
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | debian/control | 1 | ||||
-rw-r--r-- | interface-definitions/intel_qat.xml | 22 | ||||
-rw-r--r-- | interface-definitions/interfaces-openvpn.xml | 155 | ||||
-rw-r--r-- | op-mode-definitions/show-acceleration.xml | 63 | ||||
-rw-r--r-- | python/vyos/ifconfig.py | 54 | ||||
-rwxr-xr-x | src/conf_mode/accel_l2tp.py | 16 | ||||
-rwxr-xr-x | src/conf_mode/intel_qat.py | 108 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-openvpn.py | 57 | ||||
-rwxr-xr-x | src/migration-scripts/interfaces/2-to-3 | 43 | ||||
-rwxr-xr-x | src/op_mode/show_acceleration.py | 118 |
11 files changed, 578 insertions, 60 deletions
@@ -48,6 +48,7 @@ op_mode_definitions: rm -f $(OP_TMPL_DIR)/show/system/node.def rm -f $(OP_TMPL_DIR)/delete/node.def rm -f $(OP_TMPL_DIR)/reset/vpn/node.def + rm -f $(OP_TMPL_DIR)/show/system/node.def .PHONY: all all: clean interface_definitions op_mode_definitions diff --git a/debian/control b/debian/control index f7fafd828..b77a79ed9 100644 --- a/debian/control +++ b/debian/control @@ -65,6 +65,7 @@ Depends: python3, telnet, traceroute, ssl-cert, nginx-light, + vyos-qat-kernel-modules, vyos-qat-utilities ${shlibs:Depends}, ${misc:Depends} Description: VyOS configuration scripts and data diff --git a/interface-definitions/intel_qat.xml b/interface-definitions/intel_qat.xml new file mode 100644 index 000000000..5e4d5b190 --- /dev/null +++ b/interface-definitions/intel_qat.xml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<interfaceDefinition> + <node name="system"> + <children> + <node name="acceleration" owner="${vyos_conf_scripts_dir}/intel_qat.py"> + <properties> + <help>Acceleration components</help> + <priority>50</priority> + </properties> + <children> + <leafNode name="qat"> + <properties> + <help>Enable Intel QAT (Quick Assist Technology) for cryptographic acceleration</help> + <valueless/> + </properties> + </leafNode> + </children> + </node> + </children> + </node> +</interfaceDefinition> + diff --git a/interface-definitions/interfaces-openvpn.xml b/interface-definitions/interfaces-openvpn.xml index 42c953fdc..2c77bcf37 100644 --- a/interface-definitions/interfaces-openvpn.xml +++ b/interface-definitions/interfaces-openvpn.xml @@ -102,57 +102,114 @@ <valueless/> </properties> </leafNode> - <leafNode name="encryption"> + <node name="encryption"> <properties> - <help>Data Encryption Algorithm</help> - <completionHelp> - <list>des 3des bf128 bf256 aes128 aes128gcm aes192 aes192gcm aes256 aes256gcm</list> - </completionHelp> - <valueHelp> - <format>des</format> - <description>DES algorithm</description> - </valueHelp> - <valueHelp> - <format>3des</format> - <description>DES algorithm with triple encryption</description> - </valueHelp> - <valueHelp> - <format>bf128</format> - <description>Blowfish algorithm with 128-bit key</description> - </valueHelp> - <valueHelp> - <format>bf256</format> - <description>Blowfish algorithm with 256-bit key</description> - </valueHelp> - <valueHelp> - <format>aes128</format> - <description>AES algorithm with 128-bit key CBC</description> - </valueHelp> - <valueHelp> - <format>aes128gcm</format> - <description>AES algorithm with 128-bit key GCM</description> - </valueHelp> - <valueHelp> - <format>aes192</format> - <description>AES algorithm with 192-bit key CBC</description> - </valueHelp> - <valueHelp> - <format>aes192gcm</format> - <description>AES algorithm with 192-bit key GCM</description> - </valueHelp> - <valueHelp> - <format>aes256</format> - <description>AES algorithm with 256-bit key CBC</description> - </valueHelp> - <valueHelp> - <format>aes256gcm</format> - <description>AES algorithm with 256-bit key GCM</description> - </valueHelp> - <constraint> - <regex>(des|3des|bf128|bf256|aes128|aes128gcm|aes192|aes192gcm|aes256|aes256gcm)</regex> - </constraint> + <help>Data Encryption settings</help> </properties> - </leafNode> + <children> + <leafNode name="cipher"> + <properties> + <help>Standard Data Encryption Algorithm</help> + <completionHelp> + <list>des 3des bf128 bf256 aes128 aes128gcm aes192 aes192gcm aes256 aes256gcm</list> + </completionHelp> + <valueHelp> + <format>des</format> + <description>DES algorithm</description> + </valueHelp> + <valueHelp> + <format>3des</format> + <description>DES algorithm with triple encryption</description> + </valueHelp> + <valueHelp> + <format>bf128</format> + <description>Blowfish algorithm with 128-bit key</description> + </valueHelp> + <valueHelp> + <format>bf256</format> + <description>Blowfish algorithm with 256-bit key</description> + </valueHelp> + <valueHelp> + <format>aes128</format> + <description>AES algorithm with 128-bit key CBC</description> + </valueHelp> + <valueHelp> + <format>aes128gcm</format> + <description>AES algorithm with 128-bit key GCM</description> + </valueHelp> + <valueHelp> + <format>aes192</format> + <description>AES algorithm with 192-bit key CBC</description> + </valueHelp> + <valueHelp> + <format>aes192gcm</format> + <description>AES algorithm with 192-bit key GCM</description> + </valueHelp> + <valueHelp> + <format>aes256</format> + <description>AES algorithm with 256-bit key CBC</description> + </valueHelp> + <valueHelp> + <format>aes256gcm</format> + <description>AES algorithm with 256-bit key GCM</description> + </valueHelp> + <constraint> + <regex>(des|3des|bf128|bf256|aes128|aes128gcm|aes192|aes192gcm|aes256|aes256gcm)</regex> + </constraint> + </properties> + </leafNode> + <leafNode name="ncp-ciphers"> + <properties> + <help>Cipher negotiation list for use in server or client mode</help> + <completionHelp> + <list>des 3des aes128 aes128gcm aes192 aes192gcm aes256 aes256gcm</list> + </completionHelp> + <valueHelp> + <format>des</format> + <description>DES algorithm</description> + </valueHelp> + <valueHelp> + <format>3des</format> + <description>DES algorithm with triple encryption</description> + </valueHelp> + <valueHelp> + <format>aes128</format> + <description>AES algorithm with 128-bit key CBC</description> + </valueHelp> + <valueHelp> + <format>aes128gcm</format> + <description>AES algorithm with 128-bit key GCM</description> + </valueHelp> + <valueHelp> + <format>aes192</format> + <description>AES algorithm with 192-bit key CBC</description> + </valueHelp> + <valueHelp> + <format>aes192gcm</format> + <description>AES algorithm with 192-bit key GCM</description> + </valueHelp> + <valueHelp> + <format>aes256</format> + <description>AES algorithm with 256-bit key CBC</description> + </valueHelp> + <valueHelp> + <format>aes256gcm</format> + <description>AES algorithm with 256-bit key GCM</description> + </valueHelp> + <constraint> + <regex>(des|3des|aes128|aes128gcm|aes192|aes192gcm|aes256|aes256gcm)</regex> + </constraint> + <multi/> + </properties> + </leafNode> + <leafNode name="disable-ncp"> + <properties> + <help>Disable support for ncp-ciphers</help> + <valueless/> + </properties> + </leafNode> + </children> + </node> <leafNode name="hash"> <properties> <help>Hashing Algorithm</help> diff --git a/op-mode-definitions/show-acceleration.xml b/op-mode-definitions/show-acceleration.xml new file mode 100644 index 000000000..d0dcea2d6 --- /dev/null +++ b/op-mode-definitions/show-acceleration.xml @@ -0,0 +1,63 @@ +<?xml version="1.0"?> +<interfaceDefinition> + <node name="show"> + <children> + <node name="system"> + <properties> + <help>Show system information</help> + </properties> + <children> + <node name="acceleration"> + <properties> + <help>Acceleration components</help> + </properties> + <children> + <node name="qat"> + <properties> + <help>Intel QAT (Quick Assist Technology) Devices</help> + </properties> + <children> + <tagNode name="device"> + <properties> + <help>Show QAT information for a given acceleration device</help> + <completionHelp> + <script>${vyos_op_scripts_dir}/show_acceleration.py --dev_list</script> + </completionHelp> + </properties> + <children> + <node name="flows"> + <properties> + <help>Intel QAT flows</help> + </properties> + <command>${vyos_op_scripts_dir}/show_acceleration.py --flow --dev $6</command> + </node> + <node name="config"> + <properties> + <help>Intel QAT configuration</help> + </properties> + <command>${vyos_op_scripts_dir}/show_acceleration.py --conf --dev $6</command> + </node> + </children> + </tagNode> + <node name="status"> + <properties> + <help>Intel QAT status</help> + </properties> + <command>${vyos_op_scripts_dir}/show_acceleration.py --status</command> + </node> + <node name="interrupts"> + <properties> + <help>Intel QAT interrupts</help> + </properties> + <command>${vyos_op_scripts_dir}/show_acceleration.py --interrupts</command> + </node> + </children> + <command>${vyos_op_scripts_dir}/show_acceleration.py --hw</command> + </node> + </children> + </node> + </children> + </node> + </children> + </node> +</interfaceDefinition> diff --git a/python/vyos/ifconfig.py b/python/vyos/ifconfig.py index 66ccc85e9..279d948b7 100644 --- a/python/vyos/ifconfig.py +++ b/python/vyos/ifconfig.py @@ -21,6 +21,7 @@ import glob import time import vyos.interfaces + from vyos.validate import * from vyos.config import Config from vyos import ConfigError @@ -1085,6 +1086,24 @@ class EthernetIf(VLANIf): .format(self.get_driver_name())) return + # Get current flow control settings: + cmd = '/sbin/ethtool --show-pause {0}'.format(self._ifname) + tmp = self._cmd(cmd) + + # The above command returns - with tabs: + # + # Pause parameters for eth0: + # Autonegotiate: on + # RX: off + # TX: off + if re.search("Autonegotiate:\ton", tmp): + if enable == "on": + # flowcontrol is already enabled - no need to re-enable it again + # this will prevent the interface from flapping as applying the + # flow-control settings will take the interface down and bring + # it back up every time. + return + # Assemble command executed on system. Unfortunately there is no way # to change this setting via sysfs cmd = '/sbin/ethtool --pause {0} autoneg {1} tx {1} rx {1}'.format( @@ -1120,6 +1139,31 @@ class EthernetIf(VLANIf): .format(self.get_driver_name())) return + # Get current speed and duplex settings: + cmd = '/sbin/ethtool {0}'.format(self._ifname) + tmp = self._cmd(cmd) + + if re.search("\tAuto-negotiation: on", tmp): + if speed == 'auto' and duplex == 'auto': + # bail out early as nothing is to change + return + else: + # read in current speed and duplex settings + cur_speed = 0 + cur_duplex = '' + for line in tmp.splitlines(): + if line.lstrip().startswith("Speed:"): + non_decimal = re.compile(r'[^\d.]+') + cur_speed = non_decimal.sub('', line) + continue + + if line.lstrip().startswith("Duplex:"): + cur_duplex = line.split()[-1].lower() + break + + if (cur_speed == speed) and (cur_duplex == duplex): + # bail out early as nothing is to change + return cmd = '/sbin/ethtool -s {}'.format(self._ifname) if speed == 'auto' or duplex == 'auto': @@ -1496,7 +1540,7 @@ class WireGuardIf(Interface): cmd = "wg set {0} peer {1} remove".format( self._ifname, str(peerkey)) return self._cmd(cmd) - + def op_show_interface(self): wgdump = vyos.interfaces.wireguard_dump().get(self._ifname,None) @@ -1520,7 +1564,7 @@ class WireGuardIf(Interface): if wgdump['peers']: pubkey = c.return_effective_value(["peer",peer,"pubkey"]) if pubkey in wgdump['peers']: - wgpeer = wgdump['peers'][pubkey] + wgpeer = wgdump['peers'][pubkey] print (" peer: {}".format(peer)) print (" public key: {}".format(pubkey)) @@ -1543,15 +1587,15 @@ class WireGuardIf(Interface): elif int(wgpeer['latest_handshake']) == 0: """ no handshake ever """ status = "inactive" - print (" status: {}".format(status)) + print (" status: {}".format(status)) if wgpeer['endpoint'] is not None: print (" endpoint: {}".format(wgpeer['endpoint'])) if wgpeer['allowed_ips'] is not None: print (" allowed ips: {}".format(",".join(wgpeer['allowed_ips']).replace(",",", "))) - - if wgpeer['transfer_rx'] > 0 or wgpeer['transfer_tx'] > 0: + + if wgpeer['transfer_rx'] > 0 or wgpeer['transfer_tx'] > 0: rx_size =size(wgpeer['transfer_rx'],system=alternative) tx_size =size(wgpeer['transfer_tx'],system=alternative) print (" transfer: {} received, {} sent".format(rx_size,tx_size)) diff --git a/src/conf_mode/accel_l2tp.py b/src/conf_mode/accel_l2tp.py index 244a720db..37fda2029 100755 --- a/src/conf_mode/accel_l2tp.py +++ b/src/conf_mode/accel_l2tp.py @@ -125,6 +125,9 @@ gw-ip-address={{outside_nexthop}} {% if authentication['mode'] == 'local' %} [chap-secrets] chap-secrets=/etc/accel-ppp/l2tp/chap-secrets +{% if outside_nexthop %} +gw-ip-address={{outside_nexthop}} +{% endif %} {% endif %} [ppp] @@ -287,7 +290,7 @@ def get_config(): 'mppe' : 'prefer' }, 'outside_addr' : '', - 'outside_nexthop' : '', + 'outside_nexthop' : '10.255.255.0', 'dns' : [], 'dnsv6' : [], 'wins' : [], @@ -429,7 +432,16 @@ def get_config(): ### gateway address if c.exists('outside-nexthop'): config_data['outside_nexthop'] = c.return_value('outside-nexthop') - + else: + ### calculate gw-ip-address + if c.exists('client-ip-pool start'): + ### use start ip as gw-ip-address + config_data['outside_nexthop'] = c.return_value('client-ip-pool start') + elif c.exists('client-ip-pool subnet'): + ### use first ip address from first defined pool + lst_ip = re.findall("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", c.return_values('client-ip-pool subnet')[0]) + config_data['outside_nexthop'] = lst_ip[0] + if c.exists('authentication require'): auth_mods = {'pap' : 'pap','chap' : 'auth_chap_md5', 'mschap' : 'auth_mschap_v1', 'mschap-v2' : 'auth_mschap_v2'} for proto in c.return_values('authentication require'): diff --git a/src/conf_mode/intel_qat.py b/src/conf_mode/intel_qat.py new file mode 100755 index 000000000..a1abd5e81 --- /dev/null +++ b/src/conf_mode/intel_qat.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2019 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# + +import sys +import os +import re +import subprocess + +from vyos.config import Config +from vyos import ConfigError + +# Define for recovering +gl_ipsec_conf = None + +def get_config(): + c = Config() + config_data = { + 'qat_conf' : None, + 'ipsec_conf' : None, + 'openvpn_conf' : None, + } + + if c.exists('system acceleration qat'): + config_data['qat_conf'] = True + + if c.exists('vpn ipsec '): + gl_ipsec_conf = True + config_data['ipsec_conf'] = True + + if c.exists('interfaces openvpn'): + config_data['openvpn_conf'] = True + + return config_data + +# Control configured VPN service which can use QAT +def vpn_control(action): + if action == 'restore' and gl_ipsec_conf: + ret = subprocess.Popen(['sudo', 'ipsec', 'start'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + (output, err) = ret.communicate() + return + + ret = subprocess.Popen(['sudo', 'ipsec', action], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + (output, err) = ret.communicate() + +def verify(c): + # Check if QAT service installed + if not os.path.exists('/etc/init.d/vyos-qat-utilities'): + raise ConfigError("Warning: QAT init file not found") + + if c['qat_conf'] == None: + return + + # Check if QAT device exist + ret = subprocess.Popen(['sudo', 'lspci', '-nn'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + (output, err) = ret.communicate() + if not err: + data = re.findall('(8086:19e2)|(8086:37c8)|(8086:0435)|(8086:6f54)', output.decode("utf-8")) + #If QAT devices found + if not data: + print("\t No QAT acceleration device found") + sys.exit(1) + +def apply(c): + if c['ipsec_conf']: + # Shutdown VPN service which can use QAT + vpn_control('stop') + + # Disable QAT service + if c['qat_conf'] == None: + ret = subprocess.Popen(['sudo', '/etc/init.d/vyos-qat-utilities', 'stop'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + (output, err) = ret.communicate() + if c['ipsec_conf']: + vpn_control('start') + + return + + # Run qat init.d script + ret = subprocess.Popen(['sudo', '/etc/init.d/vyos-qat-utilities', 'start'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + (output, err) = ret.communicate() + + if c['ipsec_conf']: + # Recovery VPN service + vpn_control('start') + +if __name__ == '__main__': + try: + c = get_config() + verify(c) + apply(c) + except ConfigError as e: + print(e) + vpn_control('restore') + sys.exit(1) diff --git a/src/conf_mode/interfaces-openvpn.py b/src/conf_mode/interfaces-openvpn.py index cdd133904..50d367f2f 100755 --- a/src/conf_mode/interfaces-openvpn.py +++ b/src/conf_mode/interfaces-openvpn.py @@ -222,6 +222,13 @@ cipher aes-256-cbc {% endif %} {% endif %} +{%- if ncp_ciphers %} +ncp-ciphers {{ncp_ciphers}} +{% endif %} +{%- if disable_ncp %} +ncp-disable +{% endif %} + {%- if auth %} auth-user-pass /tmp/openvpn-{{ intf }}-pw auth-retry nointeract @@ -277,6 +284,7 @@ default_config_data = { 'deleted': False, 'description': '', 'disable': False, + 'disable_ncp': False, 'encryption': '', 'hash': '', 'intf': '', @@ -287,6 +295,7 @@ default_config_data = { 'local_host': '', 'local_port': '', 'mode': '', + 'ncp_ciphers': '', 'options': [], 'persistent_tunnel': False, 'protocol': '', @@ -410,10 +419,44 @@ def get_config(): if conf.exists('disable'): openvpn['disable'] = True - # data encryption algorithm - if conf.exists('encryption'): - openvpn['encryption'] = conf.return_value('encryption') - + # data encryption algorithm cipher + if conf.exists('encryption cipher'): + openvpn['encryption'] = conf.return_value('encryption cipher') + + # disable ncp-ciphers support + if conf.exists('encryption disable-ncp'): + openvpn['disable_ncp'] = True + + # data encryption algorithm ncp-list + if conf.exists('encryption ncp-ciphers'): + _ncp_ciphers = [] + for enc in conf.return_values('encryption ncp-ciphers'): + if enc == 'des': + _ncp_ciphers.append('des-cbc') + _ncp_ciphers.append('DES-CBC') + elif enc == '3des': + _ncp_ciphers.append('des-ede3-cbc') + _ncp_ciphers.append('DES-EDE3-CBC') + elif enc == 'aes128': + _ncp_ciphers.append('aes-128-cbc') + _ncp_ciphers.append('AES-128-CBC') + elif enc == 'aes128gcm': + _ncp_ciphers.append('aes-128-gcm') + _ncp_ciphers.append('AES-128-GCM') + elif enc == 'aes192': + _ncp_ciphers.append('aes-192-cbc') + _ncp_ciphers.append('AES-192-CBC') + elif enc == 'aes192gcm': + _ncp_ciphers.append('aes-192-gcm') + _ncp_ciphers.append('AES-192-GCM') + elif enc == 'aes256': + _ncp_ciphers.append('aes-256-cbc') + _ncp_ciphers.append('AES-256-CBC') + elif enc == 'aes256gcm': + _ncp_ciphers.append('aes-256-gcm') + _ncp_ciphers.append('AES-256-GCM') + openvpn['ncp_ciphers'] = ':'.join(_ncp_ciphers) + # hash algorithm if conf.exists('hash'): openvpn['hash'] = conf.return_value('hash') @@ -621,6 +664,9 @@ def verify(openvpn): if openvpn['bridge_member']: raise ConfigError('Can not delete {} as it is a member interface of bridge {}!'.format(openvpn['intf'], bridge)) + # Check if we have disabled ncp and at the same time specified ncp-ciphers + if openvpn['disable_ncp'] and openvpn['ncp_ciphers']: + raise ConfigError('Cannot specify both "encryption disable-ncp" and "encryption ncp-ciphers"') # # OpenVPN client mode - VERIFY # @@ -661,6 +707,9 @@ def verify(openvpn): if openvpn['local_address'] == openvpn['local_host']: raise ConfigError('"local-address" cannot be the same as "local-host"') + if openvpn['ncp_ciphers']: + raise ConfigError('encryption ncp-ciphers cannot be specified in site-to-site mode, only server or client') + else: if openvpn['local_address'] or openvpn['remote_address']: raise ConfigError('Cannot specify "local-address" or "remote-address" in client-server mode') diff --git a/src/migration-scripts/interfaces/2-to-3 b/src/migration-scripts/interfaces/2-to-3 new file mode 100755 index 000000000..a63a54cdf --- /dev/null +++ b/src/migration-scripts/interfaces/2-to-3 @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 + +# Change syntax of openvpn encryption settings +# - move cipher from encryption to encryption cipher +# https://phabricator.vyos.net/T1704 + +import sys +from vyos.configtree import ConfigTree + +if (len(sys.argv) < 1): + print("Must specify file name!") + sys.exit(1) + +file_name = sys.argv[1] + +with open(file_name, 'r') as f: + config_file = f.read() + +config = ConfigTree(config_file) +base = ['interfaces', 'openvpn'] + +if not config.exists(base): + # Nothing to do + sys.exit(0) +else: + # + # move cipher from "encryption" to "encryption cipher" + # + for intf in config.list_nodes(['interfaces', 'openvpn']): + # Check if encryption is set + if config.exists(['interfaces', 'openvpn', intf, 'encryption']): + # Get cipher used + cipher = config.return_value(['interfaces', 'openvpn', intf, 'encryption']) + # Delete old syntax + config.delete(['interfaces', 'openvpn', intf, 'encryption']) + # Add new syntax to config + config.set(['interfaces', 'openvpn', intf, 'encryption', 'cipher'], value=cipher) + try: + with open(file_name, 'w') as f: + f.write(config.to_string()) + except OSError as e: + print("Failed to save the modified config: {}".format(e)) + sys.exit(1) diff --git a/src/op_mode/show_acceleration.py b/src/op_mode/show_acceleration.py new file mode 100755 index 000000000..3ba0e85dd --- /dev/null +++ b/src/op_mode/show_acceleration.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2019 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +import sys +import os +import re +import argparse +import subprocess +from vyos.config import Config + +def detect_qat_dev(): + ret = subprocess.Popen(['sudo', 'lspci', '-nn'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + (output, err) = ret.communicate() + if not err: + data = re.findall('(8086:19e2)|(8086:37c8)|(8086:0435)|(8086:6f54)', output.decode("utf-8")) + #If QAT devices found + if data: + return + print("\t No QAT device found") + sys.exit(1) + +def show_qat_status(): + detect_qat_dev() + + # Check QAT service + if not os.path.exists('/etc/init.d/vyos-qat-utilities'): + print("\t QAT service not installed") + sys.exit(1) + + # Show QAT service + os.system('sudo /etc/init.d/vyos-qat-utilities status') + +# Return QAT devices +def get_qat_devices(): + ret = subprocess.Popen(['sudo', '/etc/init.d/vyos-qat-utilities', 'status'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + (output, err) = ret.communicate() + if not err: + #print(output) + data_st = output.decode("utf-8") + elm_lst = re.findall('qat_dev\d', data_st) + print('\n'.join(elm_lst)) + +# Return QAT path in sysfs +def get_qat_proc_path(qat_dev): + q_type = "" + q_bsf = "" + ret = subprocess.Popen(['sudo', '/etc/init.d/vyos-qat-utilities', 'status'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + (output, err) = ret.communicate() + if not err: + # Parse QAT service output + data_st = output.decode("utf-8").split("\n") + for elm_str in range(len(data_st)): + if re.search(qat_dev, data_st[elm_str]): + elm_list = data_st[elm_str].split(", ") + for elm in range(len(elm_list)): + if re.search('type', elm_list[elm]): + q_list = elm_list[elm].split(": ") + q_type=q_list[1] + elif re.search('bsf', elm_list[elm]): + q_list = elm_list[elm].split(": ") + q_bsf = q_list[1] + return "/sys/kernel/debug/qat_"+q_type+"_"+q_bsf+"/" + +# Check if QAT service confgured +def check_qat_if_conf(): + if not Config().exists_effective('system acceleration qat'): + print("\t system acceleration qat is not configured") + sys.exit(1) + +parser = argparse.ArgumentParser() +group = parser.add_mutually_exclusive_group() +group.add_argument("--hw", action="store_true", help="Show Intel QAT HW") +group.add_argument("--dev_list", action="store_true", help="Return Intel QAT devices") +group.add_argument("--flow", action="store_true", help="Show Intel QAT flows") +group.add_argument("--interrupts", action="store_true", help="Show Intel QAT interrupts") +group.add_argument("--status", action="store_true", help="Show Intel QAT status") +group.add_argument("--conf", action="store_true", help="Show Intel QAT configuration") + +parser.add_argument("--dev", type=str, help="Selected QAT device") + +args = parser.parse_args() + +if args.hw: + detect_qat_dev() + # Show availible Intel QAT devices + os.system('sudo lspci -nn | egrep -e \'8086:37c8|8086:19e2|8086:0435|8086:6f54\'') +elif args.flow and args.dev: + check_qat_if_conf() + os.system('sudo cat '+get_qat_proc_path(args.dev)+"fw_counters") +elif args.interrupts: + check_qat_if_conf() + # Delete _dev from args.dev + os.system('sudo cat /proc/interrupts | grep qat') +elif args.status: + check_qat_if_conf() + show_qat_status() +elif args.conf and args.dev: + check_qat_if_conf() + os.system('sudo cat '+get_qat_proc_path(args.dev)+"dev_cfg") +elif args.dev_list: + get_qat_devices() +else: + parser.print_help() + sys.exit(1)
\ No newline at end of file |