diff options
Diffstat (limited to 'python/vyos/ifconfig/interface.py')
-rw-r--r-- | python/vyos/ifconfig/interface.py | 70 |
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', {}): |