Merge lp:~mpontillo/maas/beaconing-multicast-helper into lp:~maas-committers/maas/trunk

Proposed by Mike Pontillo
Status: Merged
Approved by: Mike Pontillo
Approved revision: no longer in the source branch.
Merged at revision: 6079
Proposed branch: lp:~mpontillo/maas/beaconing-multicast-helper
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 93 lines (+89/-0)
1 file modified
scripts/maas-multicast-helper (+89/-0)
To merge this branch: bzr merge lp:~mpontillo/maas/beaconing-multicast-helper
Reviewer Review Type Date Requested Status
Lee Trager (community) Approve
Mike Pontillo (community) Abstain
Blake Rouse (community) Approve
Review via email: mp+325134@code.launchpad.net

Commit message

Add a helper script to join or leave the MAAS multicast groups.

MAAS will need to execute this on each monitored interface before listening for beacons, so that the NIC knows to forward beacon traffic up the OS (rather than dropping it before even copying it from the hardware buffer).

This approach is necessary in order to receive beacons on interfaces which may not have an IP address configured, and thus will not respond positively to socket-layer multicast join operations.

To post a comment you must log in.
Revision history for this message
Blake Rouse (blake-rouse) :
review: Needs Information
Revision history for this message
Andres Rodriguez (andreserl) wrote :
Download full text (4.3 KiB)

Another question ,

Why are we using helpers I stead of integrating this into the code?

When power scripts were effectively scripts/helpers, we decided that we
were going to move away from that in order to be more robust inside the
MAAS code base. Now with all the discovery stuff we are going again for
adding helper after helper.

Why simply not be more robust and integrate this with the code base and
stop creating helpers!?
On Tue, Jun 6, 2017 at 6:16 AM Blake Rouse <email address hidden>
wrote:

> Review: Needs Information
>
>
>
> Diff comments:
>
> > === added file 'scripts/maas-multicast-helper'
> > --- scripts/maas-multicast-helper 1970-01-01 00:00:00 +0000
> > +++ scripts/maas-multicast-helper 2017-06-06 01:27:48 +0000
> > @@ -0,0 +1,92 @@
> > +#!/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="/sbin/ip"
> > +
> > +# Note: asking the 'ip' command to join this IPv4 multicast group will
> result
> > +# in the MAC address "e0:00:00:76:00:00" being listened for on the
> interface.
> > +# Be aware that the "ip maddr show dev <ifname>" command will show the
> > +# link-layer listen address, not the IPv4-format address.
> > +IPV4_GROUP="224.0.0.118"
> > +
> > +# Note: The 'ip' command doesn't support IPv6 addresses yet.
> > +# 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
>
> Let say an interface was plugged in after MAAS has started and it doesn't
> have the multicast address. When MAAS goes to leave that group for an
> interface that doesn't have it will this fail? I believe the '|| true' will
> cause it not to fail but placing it after the '&& success' might actually
> allow it to fail.
>
> > + "$IP" maddr del "$IPV6_GROUP" dev "$1" 2> /dev/null && \
> > + success...

Read more...

Revision history for this message
Mike Pontillo (mpontillo) wrote :

Andres, a helper script is required for this because elevated privileges are required in order to add multicast groups. I looked at using the socket layer to join the multicast groups, but that doesn't work for interfaces with no IP address.

Revision history for this message
Mike Pontillo (mpontillo) wrote :

Blake, some replies to your questions below.

Revision history for this message
Blake Rouse (blake-rouse) wrote :

Thanks for the responses. Makes sense. +1 from me.

Wait on Andres review, but really don't see away around it since we need to escalate privileges.

review: Approve
Revision history for this message
Mike Pontillo (mpontillo) wrote :

I just realized that 'ip maddr add' does NOT do what one expects it to do. I wasn't paying enough attention to the resultant multicast MAC that was added to the interface. It turns out the `ip` command was just taking the IP address and directly converting the octets to a MAC.

In Twisted if I do something like `self.transport.joinGroup("224.0.0.118")` inside a DatagramProtocol, it propagates through the socket layer and joins the "01:00:5e:00:00:76" on an interface, if I believe "ip maddr show". however, "ip maddr add 224.0.0.118 dev eth0" would add the multicast MAC "e0:00:00:76:00:00" to eth0. So the script is both broken as-is, and the `ip` command is misleading.

I'll fix this before landing.

review: Needs Fixing
Revision history for this message
Mike Pontillo (mpontillo) wrote :

Fixed the above.

review: Abstain
Revision history for this message
Lee Trager (ltrager) wrote :

Two small things

1. As part of the MAAS 2.2 dev cycle we switched all of our scripts to using /bin/bash, this should use bash as well.
2. I noticed the script outputs for success but not failure. Shouldn't MAAS log when beaconing isn't setup on all devices? Reading this code we silently ignore failure.

review: Needs Information
Revision history for this message
Mike Pontillo (mpontillo) wrote :

Lee, to address your comments:

(1) I think the reason we are using /bin/sh in the scripts/ directory is because these scripts are often called using 'sudo'. Since 'sh' has more limited functionality compared to 'bash', we decided that intentionally. (in order to reduce the attack surface) I would actually have preferred to use bash, since the sh-isms in this script are a bit annoying. ;-)

(2) The script works on a best-effort basis. Not all interfaces will be able to join multicast groups, so forcing a failure isn't really helpful. Lack of success is helpful to know about, which is why a message is printed for each confirmed-successful join or leave.

Revision history for this message
Mike Pontillo (mpontillo) wrote :

Also, Lee, good suggestion about the use of 'awk'; thanks! I've made that change.

Revision history for this message
Lee Trager (ltrager) wrote :

LGTM!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'scripts/maas-multicast-helper'
2--- scripts/maas-multicast-helper 1970-01-01 00:00:00 +0000
3+++ scripts/maas-multicast-helper 2017-06-06 22:46:41 +0000
4@@ -0,0 +1,89 @@
5+#!/bin/sh -euf
6+# Copyright 2017 Canonical Ltd. This software is licensed under the
7+# GNU Affero General Public License version 3 (see the file LICENSE).
8+
9+# Helper script to join or leave MAAS-reserved multicast groups.
10+# See the IANA registries for more information:
11+# https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml
12+# https://www.iana.org/assignments/ipv6-multicast-addresses/ipv6-multicast-addresses.xhtml
13+
14+IP="/sbin/ip"
15+
16+# Note: The 'ip maddr add <mcast-address> dev <ifname>' command only supports
17+# link-layer multicast addresses. Specifying an IPv4 address will not work.
18+# This is the equivalent of "224.0.0.118".
19+IPV4_GROUP="01:00:5e:00:00:76"
20+
21+# This is the equivalent of the MAAS variable-scope multicast group, and
22+# corresponds to the link-local scoped group "ff02::15a".
23+IPV6_GROUP="33:33:00:00:01:5a"
24+
25+usage()
26+{
27+ echo "Usage: $0 <leave | join> [ifname...]" 1>&2
28+ echo " Attempts to join or leave the MAAS multicast groups." 1>&2
29+ echo " If no interfaces are specified, joins or leaves on all "`
30+ `"interfaces." 1>&2
31+}
32+
33+if [ $# -lt 1 ]; then
34+ usage
35+ exit 1
36+
37+fi
38+
39+SUCCESSES=0
40+FAILURES=""
41+
42+success()
43+{
44+ SUCCESSES=$(($SUCCESSES+1))
45+ echo "$*"
46+}
47+
48+join()
49+{
50+ "$IP" maddr add "$IPV4_GROUP" dev "$1" 2> /dev/null && \
51+ success "$1: joined $IPV4_GROUP" || true
52+ "$IP" maddr add "$IPV6_GROUP" dev "$1" 2> /dev/null && \
53+ success "$1: joined $IPV6_GROUP" || true
54+}
55+
56+leave()
57+{
58+ "$IP" maddr del "$IPV4_GROUP" dev "$1" 2> /dev/null && \
59+ success "$1: left $IPV4_GROUP" || true
60+ "$IP" maddr del "$IPV6_GROUP" dev "$1" 2> /dev/null && \
61+ success "$1: left $IPV6_GROUP" || true
62+}
63+
64+cmd="$1"
65+shift
66+
67+if [ "$#" -eq 0 ]; then
68+ interfaces="$(ip maddr show | awk '/^[0-9]*:/ { print $2 }')"
69+else
70+ interfaces="$*"
71+fi
72+
73+
74+if [ "$cmd" = "join" ]; then
75+ for ifname in $interfaces; do
76+ join "$ifname"
77+ done
78+elif [ "$cmd" = "leave" ]; then
79+ for ifname in $interfaces; do
80+ leave "$ifname"
81+ done
82+else
83+ usage
84+ exit 1
85+fi
86+
87+if [ $SUCCESSES -eq 0 ]; then
88+ echo "$0: $cmd failed. (Try re-running with 'sudo'.)" 1>&2
89+ if [ "$cmd" = "leave" ]; then
90+ echo "(This is normal if no groups were joined to begin with.)" 1>&2
91+ fi
92+ exit 2
93+fi