summaryrefslogtreecommitdiff
path: root/python/vyos/ifconfig/interface.py
diff options
context:
space:
mode:
authorjack9603301 <jack9603301@163.com>2020-12-13 17:03:01 +0800
committerjack9603301 <jack9603301@163.com>2020-12-13 17:03:01 +0800
commite08b381d07b322b8bf5daebbf2ca1c977c14d408 (patch)
tree184366bd656c34fb4c27510f8b0f6f08b8743c3c /python/vyos/ifconfig/interface.py
parent505c5efaf1e852a3e90276baacdb235c4c3e41b2 (diff)
downloadvyos-1x-e08b381d07b322b8bf5daebbf2ca1c977c14d408.tar.gz
vyos-1x-e08b381d07b322b8bf5daebbf2ca1c977c14d408.zip
interfaces: mirror: T3089: Fix the dependency problem between interfaces
Since the dependency problem has not been solved before, if the monitoring interface does not exist when the mirror rule is created, the execution will be abnormal
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', {}):