HowTo run pimd on OpenBSD
This is an introduction to HowTo run pimd on OpenBSD. I keep it around mostly as a reminder to myself when testing new pimd releases, maybe someone else can make use of it as well.
First of all, my sincere thanks to the OpenBSD team for, not just an awesome UNIX distribution, but also for their good taste in shipping a MULTICAST enabled kernel in the base distribution! On both NetBSD and FreeBSD there is a bit of work to get multicast support, which is one of the reasons for my not writing a HowTo for either of them atm.
Now, OpenBSD already ships mrouted, which is an older flood and prune based protocol called DVMRP. Their version is a few years older than the mrouted I maintain. The DVMRP protocol in mrouted uses a sort of built-in RIP to figure out how to route multicast. This was one of the first things they ripped out when creating PIM.
PIM stands for Protocol Independent Multicast, so you need to run RIP
or OSPF (or BGP or IS-IS) or whatever unicast routing protocol first
so that regular traffic works. Which is kind of useful since you can
test the network with simple ping
before trying to get any multicast
routing to work …
My topology for testing pimd
often looks something like the following.
In this HowTo the OpenBSD router is R3:
.--------. .----. .----. .----. .----------.
| Sender |----| R1 |----| R2 |----| R3 |----| Receiver |
'--------' '----' '----' '----' '----------'
So, starting out with a clean OpenBSD install we begin by setting up the basics:
- Activate unicast & multicast routing in the kernel
- Enable ripd and set system up as a multicast router
- Configure ripd
- Download & build pimd
- Run pimd
- Troubleshooting
Enable Unicast & Multicast Routing in the Kernel
cp /etc/examples/sysctl.conf /etc/
Uncomment the following two lines
net.inet.ip.forwarding=1 # 1=Permit forwarding (routing) of IPv4 packets
net.inet.ip.mforwarding=1 # 1=Permit forwarding (routing) of IPv4 multicast packets
Enable ripd and set System up as Multicast Router
Create the file /etc/rc.conf.local, unless you already have it. Add the following lines to enable ripd and enable the use of a multicast routing daemon:
# Enable ripd, also edit /etc/ripd.conf
ripd_flags="" # for normal use: ""
# Multicast routing configuration
# Please look at netstart(8) for a detailed description if you change these
multicast_host=NO # Route all multicast packets to a single interface
multicast_router=YES # A multicast routing daemon will be run, e.g. mrouted
Configure ripd
Create the file /etc/ripd.conf by using the template
cp /etc/examples/ripd.conf /etc/
Edit the file and add interface sections to all the interfaces you want
ripd to operate on, or to not operate on. Here is my ripd.conf
:
fib-update yes
redistribute connected
split-horizon poisoned
triggered-updates yes
# Do not use the WAN interface
interface pcn0 {
passive
}
# This interface is connected to R2
interface pcn1 {
cost 1
}
# This interface is connected to the client/receiver
interface pcn2 {
cost 1
}
Notice how I have redistribute connected
instead of the default.
Download & Build pimd
GitHub is the home for pimd development, the latest release is always available on the releases page. For convenience I also provide an FTP, so it is simple enough to use OpenBSD without any additional tools.
$ ftp ftp://ftp.troglobit.com/pimd/pimd-2.3.0.tar.gz
$ tar xfz pimd-2.3.0.tar.gz
$ cd pimd-2.3.0/
$ ./configure; make
You may want to install pimd
to your system when done, but you can
also run it from the build directory if you like. The default install
path is /usr/local/sbin/pimd
and /etc/pimd.conf
. Use the --prefix
and --sysconfdir
command line options to the configure script to set
other install directories. See the file INSTALL.md for more info.
That’s it!
Run pimd
The default settings in /etc/pimd.conf
should work for almost all use
cases, but it is good practise to at least disable PIM on interfaces out
to the Internet, or your local office network. In my case, like in the
case with ripd above, it is pcn0
.
Uncomment and edit the line #phyint eth0 disable
in /etc/pimd.conf
:
phyint pcn0 disable
Then you can start pimd:
pimd
To see what it is doing you can run it in the foreground with the debug command:
pimd -d
or if you simply want to see the current state. Notice how it says
DISABLED
on VIF 0, which is pcn0
:
pimd -r
Virtual Interface Table ======================================================
Vif Local Address Subnet Thresh Flags Neighbors
--- --------------- ------------------ ------ --------- -----------------
0 192.168.123.30 192.168.123 1 DISABLED
1 20.30.0.2 20.30/24 1 DR PIM 20.30.0.1
2 10.141.1.181 10.141.1/24 1 DR NO-NBR
3 20.30.0.2 register_vif0 1
Vif SSM Group Sources
Multicast Routing Table ======================================================
----------------------------------- (*,G) ------------------------------------
Source Group RP Address Flags
--------------- --------------- --------------- ---------------------------
INADDR_ANY 225.1.2.3 20.30.0.1 WC RP
Joined oifs: ....
Pruned oifs: ....
Leaves oifs: ..l.
Asserted oifs: ....
Outgoing oifs: ..o.
Incoming : .I..
TIMERS: Entry JP RS Assert VIFS: 0 1 2 3
0 40 0 0 0 0 0 0
----------------------------------- (S,G) ------------------------------------
Source Group RP Address Flags
--------------- --------------- --------------- ---------------------------
10.142.0.145 225.1.2.3 20.30.0.1 CACHE SG
Joined oifs: ....
Pruned oifs: ....
Leaves oifs: ..l.
Asserted oifs: ....
Outgoing oifs: ..o.
Incoming : .I..
TIMERS: Entry JP RS Assert VIFS: 0 1 2 3
150 5 0 0 0 0 0 0
--------------------------------- (*,*,G) ------------------------------------
Number of Groups: 1
Number of Cache MIRRORs: 1
------------------------------------------------------------------------------
You may also want to see what the OpenBSD kernel thinks about the situation when everything is working:
# netstat -g
Virtual Interface Table
Vif Thresh Limit Local-Address Remote-Address Pkt_in Pkt_out
1 1 20.30.0.2 8052 0
2 1 10.141.1.181 0 8052
3 1 20.30.0.2 0 0
Multicast Forwarding Cache
Hash Origin Mcastgroup Traffic In-Vif Out-Vifs/Forw-ttl
0 10.142.0.145 225.1.2.3
1 2/1
Total no. of entries in cache: 1
IPv6 Multicast Interface Table is empty
IPv6 Multicast Routing Table is empty
Troubleshooting
The number one problem in multicast routing is the TTL of the multicast
stream from the sender. In this example I use simple ping
, but tweak
the TTL and force the output interface:
root@sender:~# ping -I eth1 -t 10 225.1.2.3 # Linux
The second most common problem is with equipment between the sender or
the receiver and the closes router. Usually some infrastructure like a
simple switch, or as in the case with virtual setups, a software bridge.
Any one of these semi-intelligent devices can make a mess of your day.
If you suspect trouble, use ping
from the receiver (or the sender) and
use tcpdump
on the closest router. You should be able to see the ICMP
frames. If not, try disabling IGMP snooping on the swithc or software
bridge. On a Linux host system this is done by:
echo 0 > /sys/devices/virtual/net/virbr*/bridge/multicast_snooping
The third most common problem is actually the firewall in your system.
On Linux systems you get EPERM
– “Operation not permitted”, and on
OpenBSD you likely get EHOSTUNREACH
– “No route to host” all over the
logs, usually for the IGMP traffic that pimd generates. On OpenBSD this
is due to pf
by default filtering all frames with IP options set. I
added support for the “Router Alert” IP option to IGMP frames in v2.2.0,
this is recommended per RFC. Add this to your /etc/pf.conf
to allow
IGMP frames to be sent by pimd:
# Enable IGMP with Router Alert IP option
pass proto igmp allow-opts