#!/bin/sh -euf
# Copyright 2017 Canonical Ltd.  This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).

# Helper script to join or leave MAAS-reserved multicast groups.
# See the IANA registries for more information:
# https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml
# https://www.iana.org/assignments/ipv6-multicast-addresses/ipv6-multicast-addresses.xhtml

IP="ip"

# Note: The 'ip maddr add <mcast-address> dev <ifname>' command only supports
# link-layer multicast addresses. Specifying an IPv4 address will not work.
# This is the equivalent of "224.0.0.118".
IPV4_GROUP="01:00:5e:00:00:76"

# This is the equivalent of the MAAS variable-scope multicast group, and
# corresponds to the link-local scoped group "ff02::15a".
IPV6_GROUP="33:33:00:00:01:5a"

usage()
{
    echo "Usage: $0 <leave | join> [ifname...]" 1>&2
    echo "    Attempts to join or leave the MAAS multicast groups." 1>&2
    echo "    If no interfaces are specified, joins or leaves on all "`
            `"interfaces." 1>&2
}

if [ $# -lt 1 ]; then
    usage
    exit 1

fi

SUCCESSES=0
FAILURES=""

success()
{
    SUCCESSES=$(($SUCCESSES+1))
    echo "$*"
}

join()
{
    "$IP" maddr add "$IPV4_GROUP" dev "$1" 2> /dev/null && \
        success "$1: joined $IPV4_GROUP" || true
    "$IP" maddr add "$IPV6_GROUP" dev "$1" 2> /dev/null && \
        success "$1: joined $IPV6_GROUP" || true
}

leave()
{
    "$IP" maddr del "$IPV4_GROUP" dev "$1" 2> /dev/null  && \
        success "$1: left $IPV4_GROUP" || true
    "$IP" maddr del "$IPV6_GROUP" dev "$1" 2> /dev/null && \
        success "$1: left $IPV6_GROUP" || true
}

cmd="$1"
shift

if [ "$#" -eq 0 ]; then
    interfaces="$(ip maddr show | awk '/^[0-9]*:/ { print $2 }')"
else
    interfaces="$*"
fi


if [ "$cmd" = "join" ]; then
    for ifname in $interfaces; do
        join "$ifname"
    done
elif [ "$cmd" = "leave" ]; then
    for ifname in $interfaces; do
        leave "$ifname"
    done
else
    usage
    exit 1
fi

if [ $SUCCESSES -eq 0 ]; then
    echo "$0: $cmd failed. (Try re-running with 'sudo'.)" 1>&2
    if [ "$cmd" = "leave" ]; then
        echo "(This is normal if no groups were joined to begin with.)" 1>&2
    fi
    exit 2
fi
