2019-10-31 13:31:07 -05:00
|
|
|
#!/usr/bin/env python3
|
2016-12-22 11:06:56 +01:00
|
|
|
"""CRUD tests of APIs (Create, Read, Update, Delete) HLD:
|
|
|
|
|
|
|
|
- interface up/down/add/delete - interface type:
|
|
|
|
- pg (TBD)
|
|
|
|
- loopback
|
|
|
|
- vhostuser (TBD)
|
|
|
|
- af_packet (TBD)
|
|
|
|
- netmap (TBD)
|
|
|
|
- tuntap (root privileges needed)
|
|
|
|
- vxlan (TBD)
|
|
|
|
"""
|
|
|
|
|
|
|
|
import unittest
|
|
|
|
|
|
|
|
from scapy.layers.inet import IP, ICMP
|
|
|
|
from scapy.layers.l2 import Ether
|
|
|
|
|
2023-08-31 00:47:44 -04:00
|
|
|
from framework import VppTestCase
|
|
|
|
from asfframework import VppTestRunner
|
2024-03-11 10:38:46 +00:00
|
|
|
from config import config
|
2016-12-22 11:06:56 +01:00
|
|
|
|
|
|
|
|
|
|
|
class TestLoopbackInterfaceCRUD(VppTestCase):
|
2022-04-26 19:02:15 +02:00
|
|
|
"""CRUD Loopback"""
|
2016-12-22 11:06:56 +01:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def setUpClass(cls):
|
|
|
|
super(TestLoopbackInterfaceCRUD, cls).setUpClass()
|
|
|
|
try:
|
|
|
|
cls.create_pg_interfaces(range(1))
|
|
|
|
for i in cls.pg_interfaces:
|
2019-12-02 22:38:00 -05:00
|
|
|
i.config_ip4().resolve_arp()
|
2016-12-22 11:06:56 +01:00
|
|
|
except:
|
|
|
|
cls.tearDownClass()
|
|
|
|
raise
|
|
|
|
|
2019-03-12 19:23:27 -07:00
|
|
|
@classmethod
|
|
|
|
def tearDownClass(cls):
|
|
|
|
super(TestLoopbackInterfaceCRUD, cls).tearDownClass()
|
|
|
|
|
2016-12-22 11:06:56 +01:00
|
|
|
@staticmethod
|
|
|
|
def create_icmp_stream(src_if, dst_ifs):
|
|
|
|
"""
|
|
|
|
|
|
|
|
:param VppInterface src_if: Packets are send to this interface,
|
|
|
|
using this interfaces remote host.
|
|
|
|
:param list dst_ifs: IPv4 ICMP requests are send to interfaces
|
|
|
|
addresses.
|
|
|
|
:return: List of generated packets.
|
|
|
|
"""
|
|
|
|
pkts = []
|
|
|
|
for i in dst_ifs:
|
2022-04-26 19:02:15 +02:00
|
|
|
p = (
|
|
|
|
Ether(dst=src_if.local_mac, src=src_if.remote_mac)
|
|
|
|
/ IP(src=src_if.remote_ip4, dst=i.local_ip4)
|
|
|
|
/ ICMP(id=i.sw_if_index, type="echo-request")
|
|
|
|
)
|
2016-12-22 11:06:56 +01:00
|
|
|
pkts.append(p)
|
|
|
|
return pkts
|
|
|
|
|
|
|
|
def verify_icmp(self, capture, request_src_if, dst_ifs):
|
|
|
|
"""
|
|
|
|
|
|
|
|
:param capture: Capture to verify.
|
|
|
|
:param VppInterface request_src_if: Interface where was send packets.
|
|
|
|
:param list dst_ifs: Interfaces where was generated IPv4 ICMP requests.
|
|
|
|
"""
|
|
|
|
rcvd_icmp_pkts = []
|
|
|
|
for pkt in capture:
|
|
|
|
try:
|
|
|
|
ip = pkt[IP]
|
|
|
|
icmp = pkt[ICMP]
|
|
|
|
except IndexError:
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
info = (ip.src, ip.dst, icmp.type, icmp.id)
|
|
|
|
rcvd_icmp_pkts.append(info)
|
|
|
|
|
|
|
|
for i in dst_ifs:
|
|
|
|
# 0 - icmp echo response
|
|
|
|
info = (i.local_ip4, request_src_if.remote_ip4, 0, i.sw_if_index)
|
|
|
|
self.assertIn(info, rcvd_icmp_pkts)
|
|
|
|
|
2024-03-11 10:38:46 +00:00
|
|
|
@unittest.skipIf(
|
|
|
|
"ping" in config.excluded_plugins, "Exclude tests requiring Ping plugin"
|
|
|
|
)
|
2016-12-22 11:06:56 +01:00
|
|
|
def test_crud(self):
|
|
|
|
# create
|
2018-06-24 22:49:33 +02:00
|
|
|
loopbacks = self.create_loopback_interfaces(20)
|
2016-12-22 11:06:56 +01:00
|
|
|
for i in loopbacks:
|
2019-11-11 08:32:34 +00:00
|
|
|
i.local_ip4_prefix_len = 32
|
2019-12-02 22:38:00 -05:00
|
|
|
i.config_ip4().admin_up()
|
2016-12-22 11:06:56 +01:00
|
|
|
|
|
|
|
# read (check sw if dump, ip4 fib, ip6 fib)
|
2022-04-26 19:02:15 +02:00
|
|
|
if_dump = self.vapi.sw_interface_dump(
|
|
|
|
name_filter_valid=True, name_filter="loop"
|
|
|
|
)
|
2018-05-01 05:17:55 -07:00
|
|
|
fib4_dump = self.vapi.ip_route_dump(0)
|
2016-12-22 11:06:56 +01:00
|
|
|
for i in loopbacks:
|
|
|
|
self.assertTrue(i.is_interface_config_in_dump(if_dump))
|
|
|
|
self.assertTrue(i.is_ip4_entry_in_fib_dump(fib4_dump))
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
if_dump = self.vapi.sw_interface_dump(
|
|
|
|
name_filter_valid=True, name_filter="loopXYZ"
|
|
|
|
)
|
2019-10-31 14:35:21 +03:00
|
|
|
self.assertEqual(len(if_dump), 0)
|
|
|
|
|
2016-12-22 11:06:56 +01:00
|
|
|
# check ping
|
|
|
|
stream = self.create_icmp_stream(self.pg0, loopbacks)
|
|
|
|
self.pg0.add_stream(stream)
|
|
|
|
self.pg_enable_capture(self.pg_interfaces)
|
|
|
|
self.pg_start()
|
|
|
|
capture = self.pg0.get_capture(expected_count=len(stream))
|
|
|
|
|
|
|
|
self.verify_icmp(capture, self.pg0, loopbacks)
|
|
|
|
|
|
|
|
# delete
|
|
|
|
for i in loopbacks:
|
|
|
|
i.remove_vpp_config()
|
|
|
|
|
|
|
|
# read (check not in sw if dump, ip4 fib, ip6 fib)
|
|
|
|
if_dump = self.vapi.sw_interface_dump()
|
2018-05-01 05:17:55 -07:00
|
|
|
fib4_dump = self.vapi.ip_route_dump(0)
|
2016-12-22 11:06:56 +01:00
|
|
|
for i in loopbacks:
|
|
|
|
self.assertFalse(i.is_interface_config_in_dump(if_dump))
|
|
|
|
self.assertFalse(i.is_ip4_entry_in_fib_dump(fib4_dump))
|
|
|
|
|
|
|
|
# check not ping
|
|
|
|
stream = self.create_icmp_stream(self.pg0, loopbacks)
|
|
|
|
self.pg0.add_stream(stream)
|
|
|
|
self.pg_enable_capture(self.pg_interfaces)
|
|
|
|
self.pg_start()
|
|
|
|
self.pg0.assert_nothing_captured()
|
|
|
|
|
|
|
|
def test_down(self):
|
|
|
|
# create
|
2018-06-24 22:49:33 +02:00
|
|
|
loopbacks = self.create_loopback_interfaces(20)
|
2016-12-22 11:06:56 +01:00
|
|
|
for i in loopbacks:
|
2019-11-11 08:32:34 +00:00
|
|
|
i.local_ip4_prefix_len = 32
|
2019-12-02 22:38:00 -05:00
|
|
|
i.config_ip4().admin_up()
|
2016-12-22 11:06:56 +01:00
|
|
|
|
|
|
|
# disable
|
|
|
|
for i in loopbacks:
|
2019-12-02 22:38:00 -05:00
|
|
|
i.admin_down().unconfig_ip4()
|
2016-12-22 11:06:56 +01:00
|
|
|
|
|
|
|
# read (check not in sw if dump, ip4 fib, ip6 fib)
|
|
|
|
if_dump = self.vapi.sw_interface_dump()
|
2018-05-01 05:17:55 -07:00
|
|
|
fib4_dump = self.vapi.ip_route_dump(0)
|
2016-12-22 11:06:56 +01:00
|
|
|
for i in loopbacks:
|
|
|
|
self.assertTrue(i.is_interface_config_in_dump(if_dump))
|
|
|
|
self.assertFalse(i.is_ip4_entry_in_fib_dump(fib4_dump))
|
|
|
|
|
|
|
|
# check not ping
|
|
|
|
stream = self.create_icmp_stream(self.pg0, loopbacks)
|
|
|
|
self.pg0.add_stream(stream)
|
|
|
|
self.pg_enable_capture(self.pg_interfaces)
|
|
|
|
self.pg_start()
|
|
|
|
self.pg0.assert_nothing_captured()
|
|
|
|
|
|
|
|
|
2019-04-04 13:22:20 -07:00
|
|
|
class TestInterfaceDumpApiLocalOnly(VppTestCase):
|
|
|
|
"""test_interface_crud.TestInterfaceDumpApiLocalOnly"""
|
|
|
|
|
|
|
|
def test_sw_if_index_0(self):
|
|
|
|
rv = self.vapi.sw_interface_dump(sw_if_index=0)
|
|
|
|
self.assertEqual(rv[0].sw_if_index, 0)
|
|
|
|
|
|
|
|
def test_sw_if_index_twiddle0(self):
|
2022-04-26 19:02:15 +02:00
|
|
|
rv = self.vapi.sw_interface_dump(sw_if_index=0xFFFFFFFF)
|
2019-04-04 13:22:20 -07:00
|
|
|
self.assertEqual(rv[0].sw_if_index, 0)
|
|
|
|
|
|
|
|
def test_sw_if_index_1_not_existing(self):
|
|
|
|
rv = self.vapi.sw_interface_dump(sw_if_index=1)
|
2022-04-26 19:02:15 +02:00
|
|
|
self.assertEqual(len(rv), 0, "expected no records.")
|
2019-04-04 13:22:20 -07:00
|
|
|
|
|
|
|
|
|
|
|
class TestInterfaceDumpApi(VppTestCase):
|
|
|
|
"""test_interface_crud.TestInterfaceDumpApi"""
|
|
|
|
|
|
|
|
def test_sw_if_index_1(self):
|
2022-04-26 19:02:15 +02:00
|
|
|
self.vapi.create_loopback_instance(is_specified=1, user_instance=10)
|
|
|
|
self.vapi.create_loopback_instance(is_specified=1, user_instance=5)
|
2019-04-04 13:22:20 -07:00
|
|
|
|
|
|
|
# Can I get back the specified record?
|
|
|
|
rv = self.vapi.sw_interface_dump(sw_if_index=1)
|
|
|
|
self.assertEqual(rv[0].sw_if_index, 1, rv)
|
|
|
|
|
|
|
|
# verify 3 interfaces
|
2022-04-26 19:02:15 +02:00
|
|
|
rv = self.vapi.sw_interface_dump(sw_if_index=0xFFFFFFFF)
|
|
|
|
self.assertEqual(len(rv), 3, "Expected 3 interfaces.")
|
2019-04-04 13:22:20 -07:00
|
|
|
|
2019-12-02 22:38:00 -05:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
if __name__ == "__main__":
|
2016-12-22 11:06:56 +01:00
|
|
|
unittest.main(testRunner=VppTestRunner)
|