From ede2972be4c49962a04b1addb9df6ce58f2d9f42 Mon Sep 17 00:00:00 2001 From: jack9603301 Date: Thu, 3 Dec 2020 12:11:43 +0800 Subject: interface: T3089: Migrate port mirroring to vyos-1x --- .../include/interface-mirror.xml.i | 11 +++++++ interface-definitions/interfaces-bonding.xml.in | 1 + interface-definitions/interfaces-bridge.xml.in | 1 + interface-definitions/interfaces-ethernet.xml.in | 1 + python/vyos/ifconfig/interface.py | 38 +++++++++++++++++++++- smoketest/scripts/cli/base_interfaces_test.py | 28 ++++++++++++++++ smoketest/scripts/cli/test_interfaces_bonding.py | 1 + smoketest/scripts/cli/test_interfaces_bridge.py | 1 + smoketest/scripts/cli/test_interfaces_ethernet.py | 1 + 9 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 interface-definitions/include/interface-mirror.xml.i diff --git a/interface-definitions/include/interface-mirror.xml.i b/interface-definitions/include/interface-mirror.xml.i new file mode 100644 index 000000000..e3720cde7 --- /dev/null +++ b/interface-definitions/include/interface-mirror.xml.i @@ -0,0 +1,11 @@ + + + + Incoming/outgoing packet mirroring destination + + + + + + + diff --git a/interface-definitions/interfaces-bonding.xml.in b/interface-definitions/interfaces-bonding.xml.in index 66fc5f7a9..423d94f76 100644 --- a/interface-definitions/interfaces-bonding.xml.in +++ b/interface-definitions/interfaces-bonding.xml.in @@ -55,6 +55,7 @@ #include #include #include + #include Bonding transmit hash policy diff --git a/interface-definitions/interfaces-bridge.xml.in b/interface-definitions/interfaces-bridge.xml.in index 778acda78..c32c0ca32 100644 --- a/interface-definitions/interfaces-bridge.xml.in +++ b/interface-definitions/interfaces-bridge.xml.in @@ -85,6 +85,7 @@ #include #include #include + #include Interval at which neighbor bridges are removed diff --git a/interface-definitions/interfaces-ethernet.xml.in b/interface-definitions/interfaces-ethernet.xml.in index 83f3d9e46..223a94bff 100644 --- a/interface-definitions/interfaces-ethernet.xml.in +++ b/interface-definitions/interfaces-ethernet.xml.in @@ -59,6 +59,7 @@ #include #include #include + #include Configurable offload options diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index 43cd7220a..9f067b75e 100644 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -35,6 +35,7 @@ from vyos.configdict import dict_merge from vyos.template import render from vyos.util import mac2eui64 from vyos.util import dict_search +from vyos.util import cmd from vyos.template import is_ipv4 from vyos.template import is_ipv6 from vyos.validate import is_intf_addr_assigned @@ -929,7 +930,39 @@ class Interface(Control): if os.path.isfile(config_file): os.remove(config_file) - + + def get_tc_config(self,objectname): + # Parse configuration + get_tc_cmd = f'tc -j {objectname}' + tmp = cmd(get_tc_cmd, shell=True) + return json.loads(tmp) + + def del_tc_qdisc(self,dev,kind,handle): + tc_qdisc = self.get_tc_config('qdisc') + for rule in tc_qdisc: + old_dev = rule['dev'] + old_handle = rule['handle'] + old_kind = rule['kind'] + if old_dev == dev and old_handle == handle and old_kind == kind: + delete_tc_cmd = f'tc qdisc del dev {dev} handle {handle} {kind}' + self._cmd(delete_tc_cmd) + + + + def apply_mirror(self,config): + ifname = config['ifname'] + + # Remove existing mirroring rules + self.del_tc_qdisc(ifname,'ingress','ffff:') + + # Setting up packet mirroring + mirror = dict_search('mirror', config) + if mirror: + for interface in mirror: + mirror_cmd = f'tc qdisc add dev {ifname} handle ffff: ingress' + self._cmd(mirror_cmd) + mirror_cmd = f'tc filter add dev {ifname} parent ffff: protocol all prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress mirror dev {interface}' + self._cmd(mirror_cmd) def update(self, config): """ General helper function which works on a dictionary retrived by @@ -1136,6 +1169,9 @@ class Interface(Control): vif_config['ifname'] = vif_ifname vlan = VLANIf(vif_ifname, **tmp) vlan.update(vif_config) + + self.apply_mirror(config) + class VLANIf(Interface): diff --git a/smoketest/scripts/cli/base_interfaces_test.py b/smoketest/scripts/cli/base_interfaces_test.py index e02424073..0a4e85c0f 100644 --- a/smoketest/scripts/cli/base_interfaces_test.py +++ b/smoketest/scripts/cli/base_interfaces_test.py @@ -33,6 +33,7 @@ class BasicInterfaceTest: _test_vlan = False _test_qinq = False _test_ipv6 = False + _test_mirror = False _base_path = [] _options = {} @@ -66,6 +67,33 @@ class BasicInterfaceTest: self.session.commit() del self.session + + def test_mirror(self): + Success = 0 + i = 0 + if self._test_mirror: + for interface in self._interfaces: + self.session.set(self._base_path + [interface, 'mirror', 'lo']) + i+=1 + self.session.commit() + # Parse configuration + for interface in self._interfaces: + get_tc_cmd = 'tc -j qdisc' + tmp = cmd(get_tc_cmd, shell=True) + data = json.loads(tmp) + for rule in data: + dev = rule['dev'] + handle = rule['handle'] + kind = rule['kind'] + if dev == interface and handle == "ffff:" and kind == "ingress": + Success+=1 + if Success == i: + self.assertTrue(True) + else: + self.assertTrue(False) + else: + return None + def test_add_description(self): """ diff --git a/smoketest/scripts/cli/test_interfaces_bonding.py b/smoketest/scripts/cli/test_interfaces_bonding.py index ac5e01e50..93ed1ced5 100755 --- a/smoketest/scripts/cli/test_interfaces_bonding.py +++ b/smoketest/scripts/cli/test_interfaces_bonding.py @@ -34,6 +34,7 @@ class BondingInterfaceTest(BasicInterfaceTest.BaseTest): self._test_vlan = True self._test_qinq = True self._test_ipv6 = True + self._test_mirror = True self._members = [] # we need to filter out VLAN interfaces identified by a dot (.) diff --git a/smoketest/scripts/cli/test_interfaces_bridge.py b/smoketest/scripts/cli/test_interfaces_bridge.py index 3742491e8..9bddede31 100755 --- a/smoketest/scripts/cli/test_interfaces_bridge.py +++ b/smoketest/scripts/cli/test_interfaces_bridge.py @@ -31,6 +31,7 @@ class BridgeInterfaceTest(BasicInterfaceTest.BaseTest): self._test_ipv6 = True self._test_vlan = True self._test_qinq = True + self._test_mirror = True self._base_path = ['interfaces', 'bridge'] self._interfaces = ['br0'] diff --git a/smoketest/scripts/cli/test_interfaces_ethernet.py b/smoketest/scripts/cli/test_interfaces_ethernet.py index 761ec7506..bdb20a5c7 100755 --- a/smoketest/scripts/cli/test_interfaces_ethernet.py +++ b/smoketest/scripts/cli/test_interfaces_ethernet.py @@ -30,6 +30,7 @@ class EthernetInterfaceTest(BasicInterfaceTest.BaseTest): self._test_vlan = True self._test_qinq = True self._test_ipv6 = True + self._test_mirror = True self._interfaces = [] # we need to filter out VLAN interfaces identified by a dot (.) -- cgit v1.2.3