PIM-SM/SSM Multicast Routing for UNIX
Table of Contents
- Introduction
- Configuration
- Running pimd
- Troubleshooting Checklist
- Monitoring
- Large Setups
- Build & Install
- Building from GIT
- Contributing
- Origin & References
Introduction
pimd is a lightweight, stand-alone PIM-SM/SSM multicast routing daemon available under the free 3-clause BSD license. This is the restored original version from University of Southern California, by Ahmed Helmy, Rusty Eddy and Pavlin Ivanov Radoslavov.
Today pimd is maintained at GitHub. This is the preferred way to download releases, access the GIT sources, report bugs, and send patches or pull requests. Official release tarballs at the homepage and at the GitHub project's release directory.
pimd is developed on Linux and should work as-is out of the box on all major distributions. Other UNIX variants; NetBSD, FreeBSD, and Illumos, may also work, but do not receive the same amount of testing.
pimd ships with a useful pimctl tool, compatible with all PIM daemons
from the same family: pimd, pimd-dense, pim6sd. It can be a very helpful
little tool when debugging and learning PIM setups. The pimctl API is
documented in the file src/ipc.c, in case you want to use socat to
talk to pimd over its UNIX domain socket:
echo "help" |socat - UNIX-CONNECT:/var/run/pimd.sock
For a summary of changes for each release, see the ChangeLog.
Configuration
The configuration is kept in the file /etc/pimd.conf, the order of
the statements are in some cases important.
PIM-SM is a designed to be a protocol independent multicast routing protocol. As such it relies on unicast protocols like, e.g, OSPF, RIP, or static routing entries to figure out the reverse path to multicast sources. This information is necessary in setups with more than one route between a multicast sender and a receiver to figure out which PIM router should be the active forwarder.
However, pimd currently cannot retrieve the unicast routing distance (preference) and metric of routes from the system, not from the kernel nor a route manager like zebra. Hence, pimd currently needs to be setup statically on each router using the desired distance and metric for each active interface. If either the distance and/or the metric is missing in an interface configuration, the following two defaults will be used:
default-route-distance <1-255> default: 101
default-route-metric <1-1024> default: 1024
By default pimd starts up on all interfaces it can find, using the above defaults. To configure individual interfaces use:
phyint <address | ifname> ...
You can reference the interface via either its local IPv4 address or its name, e.g., eth0. Some common interface settings are:
-
disable: Disable pimd on this interface, i.e., do not send or listen for PIM-SM traffic -
dr-priority <1-4294967294>: The DR Priority option, sent in all all PIM Hello messages. Used instead of the IP address in all DR elections, if all PIM routers in LAN advertise it. The higher, the better, default 1. -
distance <1-255>: The interface's admin distance value (also confusingly referred to as metric preference in the RFC) in PIM Assert messages. Used withmetricto elect the active multicast forwarding router. Defaults todefault-route-distance -
metric <1-1024>: The cost for traversing this router. Used with thepreferencevalue above. Defaults todefault-route-metric
More interface settings are available, see the pimd(8) manual page for the full details.
The most notable feature of PIM-SM is that multicast is distributed from
so called Rendezvous Points (RP). Each RP handles distribution of one
or more multicast groups, pimd can be configured to advertise itself as
a candidate RP rp-candidate, and request to be static RP rp-address
for one or more multicast groups.
rp-address <address> [<group>[/<LENGTH> | masklen <LENGTH]
The rp-address setting is the same as the Cisco ip pim rp-address
setting to configure static Rendezvous Points. The first argument can
be an IPv4 address or a multicast group address. The default group and
prefix length is 224.0.0.0/16. Static RP's always have priority 1.
rp-candidate [address | ifname] [interval <10-16383>] [priority <0-255>] \
[group-prefix <group>[</LENGTH> | masklen <LENGTH>]]
The Rendezvous Point candidate, or CRP, setting is the same as the Cisco
ip pim rp-candidate setting. Use it to control which interface that
should be used in RP elections.
-
address | ifname: Optional local IPv4 address, or interface name to acquire address from. The default is to use the highest active IP address. -
interval <10-16383>: The CRP advertisement interval, in seconds. Default: 60 seconds -
priority <0-255>: How important this CRP is compared to others. The lower the value here, the more important the CRP. Like Cisco, pimd defaults to priority 0 when this is left out
In the CRP messages sent out by pimd, one or more multicast groups can be advertised using the following syntax.
group-prefix <group>[</LENGTH> | masklen <LENGTH>]
Each group-prefix setting defines one multicast group and an optional
mask length, which defaults to 16 if left out. A maximum of 255
multicast group prefix records is possible for the CRP.
To keep track of all Rendezvous Points in a PIM-SM domain there exists a feature called Bootstrap Router. The elected BSR in a PIM-SM domain periodically announces the RP set in Bootstrap messages. For details on PIM BSR operation, see RFC 5059.
bsr-candidate [address | ifname] [priority <0-255>] [interval <10-26214>]
The configuration of a Candidate BootStrap Router (CBSR) is very similar
to that of CRP. If either the address or the interface name is left out
pimd uses the highest active IP address. If the priority is omitted,
pimd (like Cisco) defaults to priority 0. If the interval is omitted,
it defaults to the RFC value of 60 seconds.
In a PIM-SM domain there can be two, or more, paths from a designated router (DR) for a multicast sender to reach a receiver. When receivers begin joining multicast groups all data is received via the shared tree (RPT) from each Rendezvous Point (RP). This is often not an optimal route, so when the volume starts exceeding a configurable threshold, on either the last-hop router or the RP itself, the router will attempt to switch to the shortest path tree (SPT) from the multicast source to the receiver.
In versions of pimd prior to 2.2.0 this threshold was confusingly split in two different settings, one for the DR and one for the RP. These settings are still supported, for compatibility reasons and documented in the man-page, but it is strongly recommended to change to the new syntax instead:
spt-threshold [rate <KBPS> | packets <NUM> | infinity] [interval <5-60>]
Only slightly different from the Cisco ip pim spt-threshold setting,
pimd can trigger a switch to SPT on a rate or number of packets and you
can also tweak the poll interval. It's recommended to keep the interval
in the tens of seconds, the default is 100 sec. The default threshold
is set to zero packets, which will cause a switch over to the SPT after
the first multicast packet is received.
Example
# Interface eth0 is disabled, i.e., pimd will not run there.
phyint eth0 disable
# On this LAN we have a lower numeric IP than other PIM routers
# but we want to take care of forwarding all PIM messages.
phyint eth1 dr-priority 10
# Partake in BSR elections on eth1
bsr-candidate eth1
# Offer to be an RP for all of 224.0.0.0/4
rp-candidate eth1
group-prefix 224.0.0.0 masklen 4
# This is the built-in defaults, switch to SPT on first packet
spt-threshold packets 0 interval 100
Running pimd
Having set up the configuration file, you are ready to run pimd. As
usual, it is recommended that you start it manually first, to make sure
everything works as expected, before adding it to your system's startup
scripts, with any startup flags it might need.
pimd [-hnrsv] [-f file] [-d subsys1[,...,subsysN]] [-l level]
-n: Run in foreground, with logs to stdout (for systemd and finit)-s: Use syslog, default unless-n-c file: Utilize the specified configuration file rather than the default,/etc/pimd.conf-d [subsys1,...,subsysN]: Subsystems to enable debug for when running the daemon. Optional argument, if left out, all subsystems are enabled. Typepimd -hfor a full list of subsystems-l level: Log level, one ofnone,error,warning,notice,info, ordebug. Default isnotice
Example:
pimd -f /cfg/pimd.conf
When running multiple instances of pimd, make sure to use the -I ident
argument, otherwise the PID and IPC socket files will be overwritten and
the syslog will also be hard to follow. Note, -I changes the default
.conf filename pimd looks for as well, a complete identity change.
Enabling Debug
Remember to set the correct log level when enabling debug messages,
usually you need -l debug, and -s to force messages to syslog
when running in the foreground (-n).
pimd -d igmp_proto,pim_jp,kernel,pim_register -l debug -n -s
Troubleshooting Checklist
-
Check the TTL of incoming multicast. Remember, the TTL of the multicast stream must be >1 to be routed. Or rather,
>than thenttl-thresholdof the inboundphyint -
If you see
Permission deniedin your logs, you are most likely having firewall, or SELinux, problems -
For PIM-SM, make sure you have a Rendezvous-Point (RP) in your network. Check
rp-candidate(CRP) andbsr-candidate(CBSR) settings in yourpimd.conf, orrp-addressif you prefer the static RP approach -
Check the Linux
rp_filtersetting. Many Linux systems have the "strict" setting enabled, "loose" can work but may cause problems in some setups. We recommend disabling it entirely -
PIM is protocol independent so you must have unicast routeing in place already for
pimdto work. Usepingto verify connectivity between multicast sender and receiver
Monitoring
To see the virtual interface table, including neighboring PIM routers, and the multicast routing table:
pimctl show interfaces
pimctl show neighbor
pimctl show mrt
...
The default command is pimctl show pim. To watch it continually
(notice the -c flag to watch(1) to tell it to interpret the ANSI
escape sequences):
watch -cd pimctl
See the pimctl help usage text for more commands (available only when
a running PIM daemon is available), or the pimctl(8) man page.
Also worth mentioning, pimd logs important events to the system log,
in particular at startup when it parses the pimd.conf configuration
file.
Large Setups
pimd is limited to the number of MAXVIFS interfaces listed in the
kernel headers. In Linux see /usr/include/linux/mroute.h.
To overcome this limitation, adjust the kernel #define to, e.g., 1280,
and configure pimd --with-max-vifs=1280. Please note, this has only
been tested with Linux and will likely not work with other kernels!
With this many interfaces the kernel may run out of memory to let pimd to enable IGMP on all interfaces. In Linux, use sysctl to tweak the following settings:
sysctl -w net.core.optmem_max=327680
sysctl -w net.ipv4.igmp_max_memberships=5120
Build & Install
The configure script and Makefile supports de facto standard settings
and environment variables such as --prefix=PATH and DESTDIR= for the
install process. E.g., to install pimd to /usr instead of the default
/usr/local, but redirect install to a package directory in /tmp:
./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
make
make DESTDIR=/tmp/pimd-2.3.2-1 install-strip
Building from GIT
If you want to contribute, or simply just try out the latest but unreleased features, then you need to know a few things about the GNU build system:
configure.acand a per-directoryMakefile.amare key filesconfigureandMakefile.inare generated fromautogen.shMakefileis generated byconfigurescript
To build from GIT you first need to clone the repository and run the
autogen.sh script. This requires automake and autoconf to be
installed on your system.
git clone https://github.com/troglobit/pimd.git
cd pimd/
./autogen.sh
./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var && make
GIT sources are a moving target and are not recommended for production systems, unless you know what you are doing!
Contributing
pimd is maintained by Joachim Wiberg at GitHub. If you find bugs, have feature requests, or want to contribute fixes or features, check out the code from GitHub:
git clone https://github.com/troglobit/pimd
cd pimd
See the file CONTRIBUTING.md for further details.
Origin & References
Part of this program has been derived from mrouted. The mrouted program is covered by the 3-clause BSD license in the accompanying file named LICENSE.mrouted.
The mrouted program is COPYRIGHT 2002 by The Board of Trustees of Leland Stanford Junior University.
Copyright (C) 1998-2001 University of Southern California/Information Sciences Institute All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Contributing to pimd
pimd is a very old project. As such it has a lot of history that sometimes creep up through the cracks. Bugs!
Bugs can be missing or unclear documentation, faulty legacy behavior, missing key features or support for a new cool operating system. Or simple things, like speling errors or too frequent, or missing logs.
pimd exists on GitHub for this exact purpose -- to fix bugs, collaboratively.
We welcome any and all help in the form of bug reports, fixes, patches for new features -- preferably as GitHub pull requests, submitting a pull request practically guarantees inclusion ... other methods are of course also possible: emailing the maintainer a patch or even a raw file, or simply emailing a feature request or an alert for a problem. For email questions/requests/alerts there is always the risk of memory exhaustion on the part of the maintainer.
Coding Style
Tip: Adapt your code to what the surrounding code looks like!
pimd is written in C. C is an old language and sometimes that age is clearly visible. The current maintainer has tried to (re)enforce a consistent and more modern C style, without having to completly re-indent the whole code base.
First of all, lines are allowed to be longer than 72 characters these days. In fact, there exist no enforced maximum, but keeping it around 100 chars is good practice.
pimd use leading four spaces in functions and structs. The next level
use eight spaces, but the original authors used tab for that level. A
switch() has its case statements indented four spaces ... but then
it is more or less KNF.
In Emacs this coding style can be achieved by using the following footer applied to a C file:
/**
* Local Variables:
* indent-tabs-mode: t
* c-file-style: "cc-mode"
* End:
*/
The current maintainer has considered shifting the original coding style to FULL KNF several times, but decided against changing to keep with the intent of the original authors.
Commit Messages
Commit messages exist to track why a change was made. Try to be as clear and concise as possible in your commit messages, and always, be proud of your work and set up a proper GIT identity for your commits:
git config --global user.name "Jane Doe"
git config --global user.email jane.doe@example.com
Example commit message from the Pro Git online book, notice
how git commit -s is used to automatically add a Signed-off-by:
Brief, but clear and concise summary of changes
More detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as
the subject of an email and the rest of the text as the body. The
blank line separating the ummary from the body is critical (unless
you omit the body entirely); tools like rebase can get confused if
you run the two together.
Further paragraphs come after blank lines.
- Bullet points are okay, too
- Typically a hyphen or asterisk is used for the bullet, preceded
by a single space, with blank lines in between, but conventions
vary here
Signed-off-by: Jane Doe <jane.doe@example.com>
Target Systems
pimd mainly targets modern UNIX systems and has been tested on both Debian and Ubuntu for Linux, FreeBSD, and NetBSD. Please consider these targets when submitting changes. If you cannot test on them do this, be prepared that your feature/fix will likely be delayed by the maintainer, who will attempt to test and in some cases port the feature for you.
Code of Conduct
It is expected of everyone engaging in the project to, in the words of Bill & Ted; be excellent to each other.
Contributor Code of Conduct
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery
- Personal attacks
- Trolling or insulting/derogatory comments
- Public or private harassment
- Publishing other's private information, such as physical or electronic addresses, without explicit permission
- Other unethical or unprofessional conduct.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
This Code of Conduct is adapted from the Contributor Covenant, version 1.2.0.