summaryrefslogtreecommitdiff
path: root/python/vyos/ifconfig/interface.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/vyos/ifconfig/interface.py')
-rw-r--r--python/vyos/ifconfig/interface.py70
1 files changed, 57 insertions, 13 deletions
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py
index e3c6beb8f..bf10b4440 100644
--- a/python/vyos/ifconfig/interface.py
+++ b/python/vyos/ifconfig/interface.py
@@ -13,6 +13,7 @@
# 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 netifaces import interfaces
import os
import re
import json
@@ -1044,21 +1045,59 @@ class Interface(Control):
# Setting up packet mirroring
ingress_mirror = dict_search('mirror.ingress', self._config)
if ingress_mirror:
- # 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)
+ # if interface does yet not exist bail out early and
+ # add it later
+ if 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)
egress_mirror = dict_search('mirror.egress', self._config)
if egress_mirror:
- # Mirror egress traffic
- mirror_cmd = f'tc qdisc add dev {ifname} handle 1: root prio'
- self._cmd(mirror_cmd)
- # 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)
+ # if interface does yet not exist bail out early and
+ # add it later
+ if egress_mirror in interfaces():
+ # Mirror egress traffic
+ mirror_cmd = f'tc qdisc add dev {ifname} handle 1: root prio'
+ self._cmd(mirror_cmd)
+ # 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)
+
+ def apply_mirror_of_monitor(self,mirror_rules):
+ # 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']
+
+ # Remove existing mirroring rules
+ # The rule must be completely deleted first
+ for rule in mirror_rules:
+ for intf, dire in rule.items():
+ self.del_tc_qdisc(intf,'ingress','ffff:')
+ self.del_tc_qdisc(intf,'prio','1:')
+
+ # 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)
+ # Mirror ingress traffic
+ 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 update(self, config):
""" General helper function which works on a dictionary retrived by
@@ -1227,7 +1266,12 @@ class Interface(Control):
if 'is_bridge_member' in config:
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:
+ mirror_rules = config.get('is_monitor_intf')
+ self.apply_mirror_of_monitor(mirror_rules)
+
# remove no longer required 802.1ad (Q-in-Q VLANs)
ifname = config['ifname']
for vif_s_id in config.get('vif_s_remove', {}):