Repository navigation
Conversation
There has been no way to check a configuration file without starting
the daemon. A bad file is only found when mcd exits on it, at start
or on SIGHUP, with the old configuration gone.
Like nginx -t and sshd -t. The file is read by the same parser,
errors are reported as FILE:LINE: message with exit status EX_DATAERR,
or EX_NOINPUT when the file cannot be opened. The check runs before
the root check and before daemonizing, so any user can run it:
$ mcd -t -f /etc/mcd.conf
mcd: config file /etc/mcd.conf is ok
config_init() now returns -1 when the file is missing, which main()
turns into the exit status. The daemon used to start in silence
without a configuration file, it now logs the missing file and waits
for SIGHUP as before.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
mctl takes its commands from the running daemon's help reply, so a completion script with a list of its own would drift from mcd. New hidden option, mctl -C WORD..., prints the candidates for the last word, which may be partial, from that same list, one per line, with the command's description after a tab when the word completes it. Nothing is printed when no daemon runs. The bash and zsh scripts build on it and hand mctl the line as typed, so -i NAME and -u FILE reach the daemon the command will. zsh shows the descriptions. Installed by make install. --with-bash-completion-dir=DIR and --with-zsh-completion-dir=DIR override the DATADIR defaults, or skip with =no. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A host behind a port that just came up, or that STP just put into forwarding, is not in the bridge MDB until it answers a query. With the default query interval that is up to 125 s without its streams. RFC 4541 section 2.1.1: send a general query when a port starts forwarding. netlink.c follows the bridge port state in the AF_BRIDGE link messages, seeded with a dump at start so only a change counts, and reports a port entering forwarding for its bridge. mcd queries on that bridge and on the VLAN interfaces on top of it, found through the new ifi_lower from IFLA_LINK, when it is the elected querier, followed by the usual startup burst. A flapping port gets one query per second. On by default, 'no topology-query' turns it off. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Some snooping switches learn their router ports from MRD advertisements, or from PIM, and not from IGMP/MLD queries. Behind such a switch the hosts' reports never reach mcd, and the switch keeps flooding. New iface keyword 'mrd on'. mcd then advertises itself as a multicast router on the interface: three advertisements shortly after it comes up, one every 20 s with jitter after that, one in answer to a solicitation, and a termination when the interface goes down or mcd exits. Both families, from the interface address and the link-local address like the queries. An interface in proxy mode has no address to advertise and sends nothing. Off by default, a router port receives all multicast, which a box that only runs a querier may not want. mctl show interfaces has a new MRD column. The sender side comes from https://github.com/troglobit/mrdisc, as does the solicit tool the test uses. The IGMP receive path now checks the checksum of every message, as the MLD path already did. Advertisements heard from other routers are only logged. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The Linux bridge runs every IGMP packet through ip_mc_check_igmp(), which wants the full 8 byte IGMP header and drops anything shorter as malformed. RFC 4286 solicitations and terminations are 4 bytes, so a Linux snooping switch never saw mcd's termination, and dropped solicitations on their way to it. Send both at the size of the advertisement, zero padded. Zero words do not change the checksum, so a receiver that sums only the 4 bytes of the RFC still validates it. Same for ICMPv6, and for the solicit tool in the test suite. New test, mrd-bridge.sh: a second, snooping bridge behind a veth pair learns its router port from mcd's advertisements alone, for MLD and for IGMP, with mcd's queries dropped by tc on the way in. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
mcd -n printed every message, debug included, whatever -l said. The logit() macro in log.h sends messages to prinl() when not logging to syslog, and prinl() has no level check. logger() had a level aware stderr branch, which logit() never reached. Check the level in logit() itself, for both paths, so a filtered message costs neither its argument evaluation nor its formatting. The stderr branch in logger() goes, it is the syslog path only now. The one line mcd -t prints on success goes straight to prinl(), it should show whatever -l says. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The interval was a fixed 20 s, the RFC 4286 default, while the RFC
allows 4 to 180 s.
New global keyword:
mrd-interval SEC
The jitter, 2.5 % of the interval, follows it. mctl show status
lists the value.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Advertisements from other routers were only logged, so there was no
way to see which multicast routers mcd hears on a LAN, or what they
advertise.
mcd now keeps a table per interface: an advertisement adds or
refreshes a router, with its advertisement interval, query interval
and robustness, a termination removes it. A router not heard from
within NeighborDeadInterval, 3 * (interval + jitter) per RFC 4286
section 3.5, is dropped. Routers are heard whether or not 'mrd on'
is set, at most 32 per interface.
mctl show routers [json]
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
An interface with its own query-interval still waited the global
router timeout before taking over from a querier that went silent.
With only
iface br0 enable query-interval 4
mcd waited 255 s, not 13 s. The default was computed once, at load,
from global-query-interval.
RFC 3376 section 8.5 and RFC 3810 section 9.5 compute the other
querier present interval from the interface's own query interval.
Do that for every interface, falling back to global-query-interval.
An explicit router-timeout still applies to all interfaces.
Reported by the Infix OS team.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Same as the router timeout: the group membership interval was taken
from global-query-interval, so with only
iface br0 enable query-interval 4
a group whose last member went silent stayed for 260 s, not 18 s.
Use the interface's own query interval, RFC 3376 section 8.4 and
RFC 3810 section 9.4, for the membership and compatibility mode
timers. show compat detail lists the interface's query interval.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Since 4970500 the router timeout follows the interface's own query interval, but mctl show still printed only the global value as "Router Timeout", which misleads for an interface with its own query-interval. Label it "Router Timeout (default)", like the query interval above it, and list each interface's value as router-timeout in mctl show interfaces json. The key in show status json stays as it is. Reported by the Infix OS team. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
mcd.conf(5) did not say that MRD advertisements go out whether or not mcd is the elected querier, which raised the question of whether that was intended. It is: a backup querier needs the membership reports too, so it has a group table to take over with. mctl(8) also lacked the MRD column in the show interfaces list. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.