summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/vyos/configverify.py13
-rw-r--r--python/vyos/ifconfig/__init__.py1
-rw-r--r--python/vyos/ifconfig/ethernet.py20
-rw-r--r--python/vyos/ifconfig/wwan.py28
-rw-r--r--python/vyos/remote.py51
-rw-r--r--python/vyos/xml/test_xml.py8
6 files changed, 89 insertions, 32 deletions
diff --git a/python/vyos/configverify.py b/python/vyos/configverify.py
index 88cbf2d5b..979e28b11 100644
--- a/python/vyos/configverify.py
+++ b/python/vyos/configverify.py
@@ -166,6 +166,19 @@ def verify_mirror(config):
raise ConfigError(f'Can not mirror "{direction}" traffic back ' \
'the originating interface!')
+def verify_authentication(config):
+ """
+ Common helper function used by interface implementations to perform
+ recurring validation of authentication for either PPPoE or WWAN interfaces.
+
+ If authentication CLI option is defined, both username and password must
+ be set!
+ """
+ if 'authentication' not in config:
+ return
+ if not {'user', 'password'} <= set(config['authentication']):
+ raise ConfigError('Authentication requires both username and ' \
+ 'password to be set!')
def verify_address(config):
"""
diff --git a/python/vyos/ifconfig/__init__.py b/python/vyos/ifconfig/__init__.py
index e9da1e9f5..2d3e406ac 100644
--- a/python/vyos/ifconfig/__init__.py
+++ b/python/vyos/ifconfig/__init__.py
@@ -35,3 +35,4 @@ from vyos.ifconfig.tunnel import TunnelIf
from vyos.ifconfig.wireless import WiFiIf
from vyos.ifconfig.l2tpv3 import L2TPv3If
from vyos.ifconfig.macsec import MACsecIf
+from vyos.ifconfig.wwan import WWANIf
diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py
index b89ca5a5c..07b31a12a 100644
--- a/python/vyos/ifconfig/ethernet.py
+++ b/python/vyos/ifconfig/ethernet.py
@@ -55,6 +55,11 @@ class EthernetIf(Interface):
'possible': lambda i, v: EthernetIf.feature(i, 'gso', v),
# 'shellcmd': 'ethtool -K {ifname} gso {value}',
},
+ 'lro': {
+ 'validate': lambda v: assert_list(v, ['on', 'off']),
+ 'possible': lambda i, v: EthernetIf.feature(i, 'lro', v),
+ # 'shellcmd': 'ethtool -K {ifname} lro {value}',
+ },
'sg': {
'validate': lambda v: assert_list(v, ['on', 'off']),
'possible': lambda i, v: EthernetIf.feature(i, 'sg', v),
@@ -238,6 +243,18 @@ class EthernetIf(Interface):
raise ValueError("Value out of range")
return self.set_interface('gso', 'on' if state else 'off')
+ def set_lro(self, state):
+ """
+ Enable Large Receive offload. State can be either True or False.
+ Example:
+ >>> from vyos.ifconfig import EthernetIf
+ >>> i = EthernetIf('eth0')
+ >>> i.set_lro(True)
+ """
+ if not isinstance(state, bool):
+ raise ValueError("Value out of range")
+ return self.set_interface('lro', 'on' if state else 'off')
+
def set_rps(self, state):
if not isinstance(state, bool):
raise ValueError("Value out of range")
@@ -328,6 +345,9 @@ class EthernetIf(Interface):
# GSO (generic segmentation offload)
self.set_gso(dict_search('offload.gso', config) != None)
+ # LRO (large receive offload)
+ self.set_lro(dict_search('offload.lro', config) != None)
+
# RPS - Receive Packet Steering
self.set_rps(dict_search('offload.rps', config) != None)
diff --git a/python/vyos/ifconfig/wwan.py b/python/vyos/ifconfig/wwan.py
new file mode 100644
index 000000000..f18959a60
--- /dev/null
+++ b/python/vyos/ifconfig/wwan.py
@@ -0,0 +1,28 @@
+# Copyright 2021 VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# 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 vyos.ifconfig.interface import Interface
+
+@Interface.register
+class WWANIf(Interface):
+ iftype = 'wwan'
+ definition = {
+ **Interface.definition,
+ **{
+ 'section': 'wwan',
+ 'prefixes': ['wwan', ],
+ 'eternal': 'wwan[0-9]+$',
+ },
+ }
diff --git a/python/vyos/remote.py b/python/vyos/remote.py
index 05f739dc8..80a4e7528 100644
--- a/python/vyos/remote.py
+++ b/python/vyos/remote.py
@@ -144,35 +144,30 @@ def transfer_sftp(mode, local_path, hostname, remote_path,\
sock.bind((source, 0))
sock.connect((hostname, port))
callback = make_progressbar() if progressbar else None
- try:
- with SSHClient() as ssh:
- ssh.load_system_host_keys()
- if os.path.exists(KNOWN_HOSTS_FILE):
- ssh.load_host_keys(KNOWN_HOSTS_FILE)
- ssh.set_missing_host_key_policy(InteractivePolicy())
- ssh.connect(hostname, port, username, password, sock=sock)
- with ssh.open_sftp() as sftp:
- if mode == 'upload':
- try:
- # If the remote path is a directory, use the original filename.
- if stat.S_ISDIR(sftp.stat(remote_path).st_mode):
- path = os.path.join(remote_path, os.path.basename(local_path))
- # A file exists at this destination. We're simply going to clobber it.
- else:
- path = remote_path
- # This path doesn't point at any existing file. We can freely use this filename.
- except IOError:
+ with SSHClient() as ssh:
+ ssh.load_system_host_keys()
+ if os.path.exists(KNOWN_HOSTS_FILE):
+ ssh.load_host_keys(KNOWN_HOSTS_FILE)
+ ssh.set_missing_host_key_policy(InteractivePolicy())
+ ssh.connect(hostname, port, username, password, sock=sock)
+ with ssh.open_sftp() as sftp:
+ if mode == 'upload':
+ try:
+ # If the remote path is a directory, use the original filename.
+ if stat.S_ISDIR(sftp.stat(remote_path).st_mode):
+ path = os.path.join(remote_path, os.path.basename(local_path))
+ # A file exists at this destination. We're simply going to clobber it.
+ else:
path = remote_path
- finally:
- sftp.put(local_path, path, callback=callback)
- elif mode == 'download':
- sftp.get(remote_path, local_path, callback=callback)
- elif mode == 'size':
- return sftp.stat(remote_path).st_size
- finally:
- if sock:
- sock.shutdown(socket.SHUT_RDWR)
- sock.close()
+ # This path doesn't point at any existing file. We can freely use this filename.
+ except IOError:
+ path = remote_path
+ finally:
+ sftp.put(local_path, path, callback=callback)
+ elif mode == 'download':
+ sftp.get(remote_path, local_path, callback=callback)
+ elif mode == 'size':
+ return sftp.stat(remote_path).st_size
def upload_sftp(*args, **kwargs):
transfer_sftp('upload', *args, **kwargs)
diff --git a/python/vyos/xml/test_xml.py b/python/vyos/xml/test_xml.py
index ff55151d2..3a6f0132d 100644
--- a/python/vyos/xml/test_xml.py
+++ b/python/vyos/xml/test_xml.py
@@ -59,7 +59,7 @@ class TestSearch(TestCase):
last = self.xml.traverse("interfaces")
self.assertEqual(last, '')
self.assertEqual(self.xml.inside, ['interfaces'])
- self.assertEqual(self.xml.options, ['bonding', 'bridge', 'dummy', 'ethernet', 'geneve', 'l2tpv3', 'loopback', 'macsec', 'openvpn', 'pppoe', 'pseudo-ethernet', 'tunnel', 'vxlan', 'wireguard', 'wireless', 'wirelessmodem'])
+ self.assertEqual(self.xml.options, ['bonding', 'bridge', 'dummy', 'ethernet', 'geneve', 'l2tpv3', 'loopback', 'macsec', 'openvpn', 'pppoe', 'pseudo-ethernet', 'tunnel', 'vxlan', 'wireguard', 'wireless', 'wwan'])
self.assertEqual(self.xml.filling, False)
self.assertEqual(self.xml.word, '')
self.assertEqual(self.xml.check, False)
@@ -72,7 +72,7 @@ class TestSearch(TestCase):
last = self.xml.traverse("interfaces ")
self.assertEqual(last, '')
self.assertEqual(self.xml.inside, ['interfaces'])
- self.assertEqual(self.xml.options, ['bonding', 'bridge', 'dummy', 'ethernet', 'geneve', 'l2tpv3', 'loopback', 'macsec', 'openvpn', 'pppoe', 'pseudo-ethernet', 'tunnel', 'vxlan', 'wireguard', 'wireless', 'wirelessmodem'])
+ self.assertEqual(self.xml.options, ['bonding', 'bridge', 'dummy', 'ethernet', 'geneve', 'l2tpv3', 'loopback', 'macsec', 'openvpn', 'pppoe', 'pseudo-ethernet', 'tunnel', 'vxlan', 'wireguard', 'wireless', 'wwan'])
self.assertEqual(self.xml.filling, False)
self.assertEqual(self.xml.word, last)
self.assertEqual(self.xml.check, False)
@@ -85,7 +85,7 @@ class TestSearch(TestCase):
last = self.xml.traverse("interfaces w")
self.assertEqual(last, 'w')
self.assertEqual(self.xml.inside, ['interfaces'])
- self.assertEqual(self.xml.options, ['wireguard', 'wireless', 'wirelessmodem'])
+ self.assertEqual(self.xml.options, ['wireguard', 'wireless', 'wwan'])
self.assertEqual(self.xml.filling, True)
self.assertEqual(self.xml.word, last)
self.assertEqual(self.xml.check, True)
@@ -276,4 +276,4 @@ class TestSearch(TestCase):
self.assertEqual(self.xml.filled, True)
self.assertEqual(self.xml.plain, False)
- # Need to add a check for a valuless leafNode \ No newline at end of file
+ # Need to add a check for a valuless leafNode