Linux-Mrouted-MiniHOWTO

How to set up Linux for multicast routing

Bart Trojanowski <bart@jukie.net>
v0.1, 30 October 1999

This document is not a formal how to but a list of steps that I folloed to get a multicast routing Linux box.  I will also give some simple source code at the end to get you started in writing multicast programs.  Which is what I needed multicast routing for -- to test my code.  Please not that mrouted (the multicast router) is not distributed via the normal Linux distribution channels because it's not free software.  Read the license that comes with it before you use it.  Also note that even though it is not implicitly specified you are expected to become root for most of these operations.

0. Multicast

Multicast is protocol that has been around for a while and I recomend that you read over the Multicast-HOWO (referenced in section 5) to learn how it works.  I recomend that you do that first or at least know it's there to answer questions this document will not.

1. The software required

You don't need to run the same exact software as I.  My list is just a guide.

I started with a custom install of RedHat 6.0.  And then installed these from source:

If these files don't exist you can use http://www.tuxfinder.com/ or http://www.filewatcher.org/ to find them.

2. The kernel

If you have configured the kernel before and are familiar with the tools you can skip over this section -- simply make sure that you have the following items set:
    CONFIG_IP_MULTICAST=y
    CONFIG_IP_ROUTER=y
    CONFIG_IP_MROUTE=y
    CONFIG_NET_IPIP=y

2.1 Installing the kernel sourcetree

Most comonly the source for the kernel are kept in /usr/src/linux -- most distributions put them there.  So if you downloaded your linux-2.2.12.tar.gz file to /tmp you may want to do the following:
cd /usr/src
mv linux linux-old
tar xvzf /tmp/linux-2.2.12.tar.gz
And now you have the linux source tree.  Since the directory created by the last command is /usr/src/linux, I usually rename it to its proper name (including its version) and simply provide a 'linux' symbolic link to the new name to avoid any compatility issues.
mv linux linux-2.2.12
ln -s linux-2.2.12 linux
Ok, so now we are ready to configure our kernel.

2.2 Configuring the kernel

There are four ways of configuring the kernel.  The first is fairly crude and I just include it for completeness: editing the .config file ... yuk!  The next is not much better: 'make config' -- it's a program that will ask you for a yes/no/module for every one of the 500 options in the kernel.  The next two are vary nice menu driven utilities: 'make menuconfig' and 'make xconfig'.  As I don't often have X installed on the systems I use I frequently use the curses based menuconfig feature.

You need these features to get multicast routing to work:

And of course you will require some kind of a network interface (I leave that upto you).

2.3 Compiling and installing the kernel

This may very from system to system.  I use a i86 RedHat 6.0 and this is what I do:
make bzImage
make install
make modules
make modules_install

2.4 Installing LILO

You must modify your LILO to point and boot from the new kernel.  To do this edit your /etc/lilo.conf file and make it look like this:
boot=/dev/hda
map=/boot/map
install=/boot/boot.b
prompt
timeout=50
vga=ask

default=linux-mcr

image=/boot/vmlinuz-2.2.12-mcr
        label=linux-mcr
        read-only
        root=/dev/hda2

image=/boot/vmlinuz-2.2.5-15
        label=linux-5-15
        read-only
        root=/dev/hda2

Of course you must specify the correct harddrive device for the 'boot' and 'root' labels.  If you have not done this before best to read the Kernel-HOWTO.

Once you have altered your lilo.conf you can reinstall LILO:

lilo
And that's it.  Reboot.

3. Mrouted

As mentioned before mrouted is not free -- read the license file.
 

3.1 Untaring and patching the sources

Once again I assume that you have downloaded the files into /tmp and wish to untar them in /usr/src.
cd /usr/src
tar xvzf /tmp/mrouted-3.9-beta3.tar.gz
gunzip /tmp/mrouted_3.9-beta3-1.diff.gz | patch -p0
If everything goes well it should tell you that it patched ~13 files.  I get this output:
patching file `mrouted-3.9-beta3.orig/Makefile'
patching file `mrouted-3.9-beta3.orig/defs.h'
patching file `mrouted-3.9-beta3.orig/pathnames.h'
patching file `mrouted-3.9-beta3.orig/debian/init.d'
patching file `mrouted-3.9-beta3.orig/debian/changelog'
patching file `mrouted-3.9-beta3.orig/debian/copyright'
patching file `mrouted-3.9-beta3.orig/debian/dirs'
patching file `mrouted-3.9-beta3.orig/debian/control'
patching file `mrouted-3.9-beta3.orig/debian/rules'
patching file `mrouted-3.9-beta3.orig/debian/README.debian'
patching file `mrouted-3.9-beta3.orig/igmp.i'
patching file `mrouted-3.9-beta3.orig/netinet/ip_mroute.h'
patching file `mrouted-3.9-beta3.orig/vers.c'

3.2 Compiling

So now we are ready to compile:
cd mrouted-3.9-beta3.orig
make

3.3 Configuring the router

Once it compiles let's create a file /etc/mrouted.conf, it will include:
phyint eth0 rate_limit 0 igmpv1
phyint eth1 rate_limit 0 igmpv1
There is a lot more that you can configure in the mrouted.conf and you should probably read the mrouted.conf example that comes with the sources --  it's well commented.  The above 2 lines force the mrouted program to enforce igmp V1 on eth0 and eth1 with no rate limit.  More importantly it works for me.

Delbert Matlock, the maintainer of "Multicast and MBONE on Linux", had an incompatibility with mrouted and virtual interfaces. He was able to overcome this by adding the following line (for each of his virtual devices into the /etc/mrouted.conf.
phyint eth0:0 disable

3.4 Running the router

There are a few issues that must be taken care off before we run the router.  First we need to have those interfaces that are specified in the configuration.  Next we must have a default route setup for the multicast traffic; to do this run:
route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0
You can use any network device so long as that is where you want the default data to go to.

Finally you can run the mrouted program:

mrouted -c /etc/mrouted.conf -d
The '-d' flag is useful the first time to see the 'debug' output more on this in the manpage for mrouted (mrouted.8).

4. Multicast programming

At this point you should be routing multicast packets.  Note that multicast routing is not instantatious and sometimes may requires a half a minute to start up.  Most important to understand about multicast routing is that if no one requests the packets on network of eth1 they will jump accross from eth0 to eth1.

In this secion I will give a code example for a simple multicast program.  As just mentioned the reader must request the packets in order to be garanteed that they are routed towards it.  This is called 'joining a group'.  And a multicast group is identified by it's IP address.  If a socket does not join a multicast group no packets of that group will ever be passed to it by the kernel.

Sending multicast is no different then sending UDP packets.  The sender does not even have to join the multicast group in order to send to it.  However, it is proper to join the group and inform the mrouted program that we are sending trafic on that multicast group.  Even more important for the multicast sender is to set the TTL to something greater then 1 (which is the default).  TTL, or time to live, is a counter attached to every sent packet.  The TTL value gets decremented at every router and when it reaches 0 is dropped.  Thus multicast data will not get very far if the TTL value is 1.

Here is some code to get you going:

int main(void)
{
  const int TTL=64;
  char buffer[BUFFSIZE];
  const int v_off=0, v_on=1;
  struct sockaddr_in to;
  struct ip_mreq multiaddr;
  int m;

  int sock = socket(AF_INET, SOCK_DGRAM, 0);

  // Join a multicast group 224.1.1.1 on all interfaces
  multiaddr.imr_multiaddr.s_addr = htonl(0xe0010104); // 224.1.1.1
  multiaddr.imr_interface.s_addr = htonl(INADDR_ANY);
  setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
                 &multiaddr, sizeof(multiaddr));

  setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL,
                 &TTL, sizeof(TTL));

  // setup the destination address of 224.1.1.1 and UDP port 2007
  to.sin_family = AF_INET;
  to.sin_addr.s_addr = htonl(0xe0010104);
  to.sin_port = htons(2007);

  // write some data
  for(m=0;m<1000000;m++)
  {
    sendto(sock,buffer,BUFFSIZE, 0,
           (const struct sockaddr*)&to,sizeof(to));
  }

  // tell router we are no longer interested in this group
  close(sock);
}

5. Resources

Google search on multicast routing on linux yields many good results: This is how I found the Delbert Matlock's page titled "Multicast and MBONE on Linux": To find out how multicast works read this HOWTO:


You can find this HOWTO at http://www.jukie.net/~bart/multicast/
Copyright Bart Trojanowski, 1999/10/30
You are free to distribute this document if you leave this acknowledgement in the file.