Multicast Driver Testing Quick How-To v 0.3 [was: Re: List of pending v2.4 kernel bugs]

From: Roger Luethi
Date: Thu Aug 05 2004 - 08:39:54 EST


On Fri, 30 Jul 2004 20:20:06 +0200, Roger Luethi wrote:
> Hmm.. Maybe I should brush up the multicast testing quick how-to and
> post it somewhere for future reference. There seems to be a distinct
> lack of testing in this area.

Related information: As of Linux 2.6.7, results for atp, winbond, and
tulip_core would be most interesting. For 2.4.26, candidates include
winbond and tulip_core.

Here goes:

================================================================================
Multicast Driver Testing Quick How-To (Version 0.3)
=====================================
0.2 - Add minimal test app by David Stevens
0.3 - Spell out limitations on Ethernet switches (David Stevens)
- Link to Manfred Spraul's test app

This document is meant to facilitate testing of basic multicast
functionality in Linux (Ethernet) drivers.

1) Preparation
--------------
Make sure the host you are testing replies to broadcasts:

target# cat /proc/sys/net/ipv4/icmp_echo_ignore_all
0
target# cat /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
0

Our test packets need to go to the target host, so either have a
route or use ping "-r -I <ifname>" option:
tester# route add -net 224.0.0.0 netmask 240.0.0.0 eth0

2) Test default group
---------------------
Since every multicast capable host interface joins 224.0.0.1, you
can already ping your target:

tester# ping -r -I eth0 -t 1 -c 2 224.0.0.1

Your target host should answer this (so may your tester, depending on
your setup).

3a) Join group on Ethernet level
--------------------------------
Note: If you add multicast addresses via "ip maddr" in the way described
below, it won't work for some hardware configurations. In particular,
if you have an Ethernet switch that does IGMP snooping, the switch won't
replicate multicast packets on ports that haven't had IGMP reports for
the multicast address you're testing. In that case, having it in the
hardware MAF (Multicast Address Filter) doesn't help, and you'll need
to do the IP-level join (see 3b) to get them delivered.


We haven't joined the next group yet, so there should be no answer:

tester# ping -r -I eth0 -t 1 -c 2 224.1.1.37

Use packet sniffer to confirm that target is not seeing the request
(use -p option for tcpdump or tethereal to prevent promiscuous mode)

Now join the group (Ethernet level):

target# ip maddr add 01:00:5e:01:01:25 dev eth0

tester# ping -r -I eth0 -t 1 -c 2 224.1.1.37

Use packet sniffer to confirm that target is seeing the request now.

3b) Join group on IP level
--------------------------
The program below will join a multicast group at IP level and thus
at Ethernet level as well -- provided driver and hardware work
properly. Group membership end with termination of the program.

Remove hardware filter (if any left from previous test):

target# ip maddr del 01:00:5e:01:01:25 dev eth0

Join multicast group:

target# ./mcjoin eth0 224.1.1.37

tester# ping -r -I eth0 -t 1 -c 2 224.1.1.37

No need for packet sniffer this time, the target will answer since the
IP layer is aware of our group membership.

A) Other Resources
------------------
Manfred Spraul maintains a multicast test application at:
http://www.colorfullife.com/~manfred/TestApps/multicast/

--------------------------------------------------------------------------------
/* Purpose: Join a multicast group (for testing) */
/* Author: David Stevens <dlstevens at us.ibm.com>, 2004 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <net/if.h>

int
main(int argc, char *argv[])
{
struct ip_mreqn mreqn;
int s;

if (argc != 3) {
fprintf(stderr, "usage: %s <dev> <group>\n", argv[0]);
exit(1);
}
s = socket(PF_INET, SOCK_DGRAM, 0);
if (s < 0) {
perror("socket");
exit(1);
}
memset(&mreqn, 0, sizeof(mreqn));
mreqn.imr_ifindex = if_nametoindex(argv[1]);
if (!mreqn.imr_ifindex) {
fprintf(stderr, "%s: \"%s\" invalid interface\n", argv[0],
argv[1]);
exit(1);
}
if (inet_pton(AF_INET, argv[2], &mreqn.imr_multiaddr) <= 0) {
fprintf(stderr, "%s: \"%s\" invalid group address\n", argv[0],
argv[2]);
exit(1);
}
if (setsockopt(s, SOL_IP, IP_ADD_MEMBERSHIP, &mreqn,sizeof mreqn) < 0) {
perror("IP_ADD_MEMBERSHIP");
exit(1);
}
printf("joined group %s on %s (pausing...)\n", argv[2], argv[1]);
fflush(stdout);
pause();
exit(0);
}
--------------------------------------------------------------------------------
================================================================================

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/