diff options
| author | Christian Breunig <christian@breunig.cc> | 2024-01-22 15:01:36 +0100 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-22 15:01:36 +0100 | 
| commit | 90a50f8c21433188257766be1b971cae365a7a0c (patch) | |
| tree | 60cff2a88751601e0938b7d707288aced5ffc4d8 | |
| parent | adc4d381a56e94b3544f06b670c5285d4d0f2a89 (diff) | |
| parent | 3eea8dbed1bd201373eb8a452239d9565d468b33 (diff) | |
| download | vyos-1x-90a50f8c21433188257766be1b971cae365a7a0c.tar.gz vyos-1x-90a50f8c21433188257766be1b971cae365a7a0c.zip | |
Merge pull request #2871 from c-po/multicast-T5969
op-mode: T5969: list multicast group membership
| -rw-r--r-- | data/op-mode-standardized.json | 7 | ||||
| -rw-r--r-- | op-mode-definitions/multicast-group.xml.in | 63 | ||||
| -rw-r--r-- | op-mode-definitions/show-ip-multicast.xml.in | 3 | ||||
| -rwxr-xr-x | src/op_mode/multicast.py | 72 | 
4 files changed, 139 insertions, 6 deletions
| diff --git a/data/op-mode-standardized.json b/data/op-mode-standardized.json index ed9bb6cad..d3685caaf 100644 --- a/data/op-mode-standardized.json +++ b/data/op-mode-standardized.json @@ -9,21 +9,22 @@  "dhcp.py",  "dns.py",  "interfaces.py", +"ipsec.py",  "lldp.py",  "log.py",  "memory.py", +"multicast.py",  "nat.py",  "neighbor.py",  "nhrp.py",  "openconnect.py", -"otp.py",  "openvpn.py", +"otp.py",  "reset_vpn.py",  "reverseproxy.py",  "route.py", -"system.py", -"ipsec.py",  "storage.py", +"system.py",  "uptime.py",  "version.py",  "vrf.py" diff --git a/op-mode-definitions/multicast-group.xml.in b/op-mode-definitions/multicast-group.xml.in new file mode 100644 index 000000000..39b4e347c --- /dev/null +++ b/op-mode-definitions/multicast-group.xml.in @@ -0,0 +1,63 @@ +<?xml version="1.0"?> +<interfaceDefinition> +  <node name="show"> +    <children> +      <node name="ip"> +        <children> +          <node name="multicast"> +            <properties> +              <help>Show IP multicast</help> +            </properties> +            <children> +              <node name="group"> +                <properties> +                  <help>Show IP multicast group membership</help> +                </properties> +                <command>${vyos_op_scripts_dir}/multicast.py show_group --family inet</command> +                <children> +                  <tagNode name="interface"> +                    <properties> +                      <help>Show IP multicast group membership of specific interface</help> +                      <completionHelp> +                        <script>${vyos_completion_dir}/list_interfaces</script> +                      </completionHelp> +                    </properties> +                    <command>${vyos_op_scripts_dir}/multicast.py show_group --family inet --interface "$6"</command> +                  </tagNode> +                </children> +              </node> +            </children> +          </node> +        </children> +      </node> +      <node name="ipv6"> +        <children> +          <node name="multicast"> +            <properties> +              <help>Show IPv6 multicast</help> +            </properties> +            <children> +              <node name="group"> +                <properties> +                  <help>Show IPv6 multicast group membership</help> +                </properties> +                <command>${vyos_op_scripts_dir}/multicast.py show_group --family inet6</command> +                <children> +                  <tagNode name="interface"> +                    <properties> +                      <help>Show IP multicast group membership of specific interface</help> +                      <completionHelp> +                        <script>${vyos_completion_dir}/list_interfaces</script> +                      </completionHelp> +                    </properties> +                    <command>${vyos_op_scripts_dir}/multicast.py show_group --family inet6 --interface "$6"</command> +                  </tagNode> +                </children> +              </node> +            </children> +          </node> +        </children> +      </node> +    </children> +  </node> +</interfaceDefinition> diff --git a/op-mode-definitions/show-ip-multicast.xml.in b/op-mode-definitions/show-ip-multicast.xml.in index 605d61e8d..00a4704c7 100644 --- a/op-mode-definitions/show-ip-multicast.xml.in +++ b/op-mode-definitions/show-ip-multicast.xml.in @@ -5,9 +5,6 @@        <node name="ip">          <children>            <node name="multicast"> -            <properties> -              <help>Show IP multicast</help> -            </properties>              <children>                <leafNode name="interface">                  <properties> diff --git a/src/op_mode/multicast.py b/src/op_mode/multicast.py new file mode 100755 index 000000000..0666f8af3 --- /dev/null +++ b/src/op_mode/multicast.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2024 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program.  If not, see <http://www.gnu.org/licenses/>. + +import json +import sys +import typing + +from tabulate import tabulate +from vyos.utils.process import cmd + +import vyos.opmode + +ArgFamily = typing.Literal['inet', 'inet6'] + +def _get_raw_data(family, interface=None): +    tmp = 'ip -4' +    if family == 'inet6': +        tmp = 'ip -6' +    tmp = f'{tmp} -j maddr show' +    if interface: +        tmp = f'{tmp} dev {interface}' +    output = cmd(tmp) +    data = json.loads(output) +    if not data: +        return [] +    return data + +def _get_formatted_output(raw_data): +    data_entries = [] + +    # sort result by interface name +    for interface in sorted(raw_data, key=lambda x: x['ifname']): +        for address in interface['maddr']: +            tmp = [] +            tmp.append(interface['ifname']) +            tmp.append(address['family']) +            tmp.append(address['address']) + +            data_entries.append(tmp) + +    headers = ["Interface", "Family", "Address"] +    output = tabulate(data_entries, headers, numalign="left") +    return output + +def show_group(raw: bool, family: ArgFamily, interface: typing.Optional[str]): +    multicast_data = _get_raw_data(family=family, interface=interface) +    if raw: +        return multicast_data +    else: +        return _get_formatted_output(multicast_data) + +if __name__ == "__main__": +    try: +        res = vyos.opmode.run(sys.modules[__name__]) +        if res: +            print(res) +    except (ValueError, vyos.opmode.Error) as e: +        print(e) +        sys.exit(1) | 
