summaryrefslogtreecommitdiff
path: root/python/vyos/ifconfig
diff options
context:
space:
mode:
Diffstat (limited to 'python/vyos/ifconfig')
-rw-r--r--python/vyos/ifconfig/interface.py120
1 files changed, 39 insertions, 81 deletions
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py
index 9a1483a1e..163ab2f6a 100644
--- a/python/vyos/ifconfig/interface.py
+++ b/python/vyos/ifconfig/interface.py
@@ -1008,86 +1008,45 @@ class Interface(Control):
if os.path.isfile(config_file):
os.remove(config_file)
- def apply_mirror(self):
+ def set_mirror(self):
# Please refer to the document for details
- # https://man7.org/linux/man-pages/man8/tc.8.html
- # https://man7.org/linux/man-pages/man8/tc-mirred.8.html
- ifname = self._config['ifname']
+ # - https://man7.org/linux/man-pages/man8/tc.8.html
+ # - https://man7.org/linux/man-pages/man8/tc-mirred.8.html
+ # Depening if we are the source or the target interface of the port
+ # mirror we need to setup some variables.
+ source_if = self._config['ifname']
+ config = self._config.get('mirror', None)
+
+ if 'is_mirror_intf' in self._config:
+ source_if = next(iter(self._config['is_mirror_intf']))
+ config = self._config['is_mirror_intf'][source_if]
+
# Remove existing mirroring rules
- try:
- delete_tc_cmd = f'tc qdisc del dev {ifname} handle ffff: ingress'
- self._cmd(delete_tc_cmd)
- except:
- pass
- try:
- delete_tc_cmd = f'tc qdisc del dev {ifname} handle 1: root prio'
- self._cmd(delete_tc_cmd)
- except:
- pass
-
- # Setting up packet mirroring
- ingress_mirror = dict_search('mirror.ingress', self._config)
- # if interface does yet not exist bail out early and
- # add it later
- if ingress_mirror and ingress_mirror in interfaces():
- # Mirror ingress traffic
- mirror_cmd = f'tc qdisc add dev {ifname} handle ffff: ingress'
- self._cmd(mirror_cmd)
- # Export the mirrored traffic to the interface
- 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 {ingress_mirror}'
- self._cmd(mirror_cmd)
+ delete_tc_cmd = f'tc qdisc del dev {source_if} handle ffff: ingress; '
+ delete_tc_cmd += f'tc qdisc del dev {source_if} handle 1: root prio'
+ self._popen(delete_tc_cmd)
+
+ # Bail out early if nothing needs to be configured
+ if not config:
+ return
+
+ for direction, mirror_if in config.items():
+ if mirror_if not in interfaces():
+ continue
+
+ if direction == 'ingress':
+ handle = 'ffff: ingress'
+ parent = 'ffff:'
+ elif direction == 'egress':
+ handle = '1: root prio'
+ parent = '1:'
- egress_mirror = dict_search('mirror.egress', self._config)
- # if interface does yet not exist bail out early and
- # add it later
- if egress_mirror and egress_mirror in interfaces():
# Mirror egress traffic
- mirror_cmd = f'tc qdisc add dev {ifname} handle 1: root prio'
- self._cmd(mirror_cmd)
+ mirror_cmd = f'tc qdisc add dev {source_if} handle {handle}; '
# Export the mirrored traffic to the interface
- mirror_cmd = f'tc filter add dev {ifname} parent 1: protocol all prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress mirror dev {egress_mirror}'
- self._cmd(mirror_cmd)
+ mirror_cmd += f'tc filter add dev {source_if} parent {parent} protocol all prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress mirror dev {mirror_if}'
+ self._popen(mirror_cmd)
- def apply_mirror_of_monitor(self):
- # Please refer to the document for details
- # https://man7.org/linux/man-pages/man8/tc.8.html
- # https://man7.org/linux/man-pages/man8/tc-mirred.8.html
- ifname = self._config['ifname']
- mirror_rules = self._config.get('is_monitor_intf')
-
- # Remove existing mirroring rules
- # The rule must be completely deleted first
- for rule in mirror_rules:
- for intf, dire in rule.items():
- try:
- delete_tc_cmd = f'tc qdisc del dev {intf} handle ffff: ingress'
- self._cmd(delete_tc_cmd)
- except:
- pass
- try:
- delete_tc_cmd = f'tc qdisc del dev {intf} handle 1: root prio'
- self._cmd(delete_tc_cmd)
- except:
- pass
-
- # Setting mirror rules
- for rule in mirror_rules:
- for intf, dire in rule.items():
- # Setting up packet mirroring
- if dire == "ingress":
- # Mirror ingress traffic
- mirror_cmd = f'tc qdisc add dev {intf} handle ffff: ingress'
- self._cmd(mirror_cmd)
- # Export the mirrored traffic to the interface
- mirror_cmd = f'tc filter add dev {intf} parent ffff: protocol all prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress mirror dev {ifname}'
- self._cmd(mirror_cmd)
- elif dire == "egress":
- # Mirror egress traffic
- mirror_cmd = f'tc qdisc add dev {intf} handle 1: root prio'
- self._cmd(mirror_cmd)
- # Export the mirrored traffic to the interface
- mirror_cmd = f'tc filter add dev {intf} parent 1: protocol all prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress mirror dev {ifname}'
- self._cmd(mirror_cmd)
def set_xdp(self, state):
"""
@@ -1281,13 +1240,12 @@ class Interface(Control):
bridge_dict = config.get('is_bridge_member')
self.add_to_bridge(bridge_dict)
- # Re-set rules for the mirror monitoring interface
- if 'is_monitor_intf' in config:
- self.apply_mirror_of_monitor()
-
# eXpress Data Path - highly experimental
self.set_xdp('xdp' in config)
+ # configure port mirror
+ self.set_mirror()
+
# remove no longer required 802.1ad (Q-in-Q VLANs)
ifname = config['ifname']
for vif_s_id in config.get('vif_s_remove', {}):
@@ -1338,9 +1296,6 @@ class Interface(Control):
vlan = VLANIf(vif_ifname, **tmp)
vlan.update(vif_config)
- self.apply_mirror()
-
-
class VLANIf(Interface):
""" Specific class which abstracts 802.1q and 802.1ad (Q-in-Q) VLAN interfaces """
@@ -1417,6 +1372,9 @@ class VLANIf(Interface):
return super().set_admin_state(state)
+ def set_mirror(self):
+ return
+
def update(self, config):
""" General helper function which works on a dictionary retrived by
get_config_dict(). It's main intention is to consolidate the scattered