Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem building and running SMCRoute on FreeBSD #5

Closed
macfreek opened this issue Sep 16, 2014 · 16 comments
Closed

Problem building and running SMCRoute on FreeBSD #5

macfreek opened this issue Sep 16, 2014 · 16 comments

Comments

@macfreek
Copy link

smcroute did not compile on FreeBSD 10.0. I have not yet investigated it, due to a deadline at work in 2 weeks. I'll have a look later. This report is just to track this for myself.

I suspect it has to do with changes in FreeBSD with the compiler, but that is just a hunch.

[root@wolfje] ~/smcroute-1.99.2# ./configure
checking for gcc... no
checking for cc... cc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether cc accepts -g... yes
checking for cc option to accept ISO C89... none needed
checking how to run the C preprocessor... cc -E
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking minix/config.h usability... no
checking minix/config.h presence... no
checking for minix/config.h... no
checking whether it is safe to define __EXTENSIONS__... yes
checking for ANSI C header files... (cached) yes
checking arpa/inet.h usability... yes
checking arpa/inet.h presence... yes
checking for arpa/inet.h... yes
checking fcntl.h usability... yes
checking fcntl.h presence... yes
checking for fcntl.h... yes
checking netinet/in.h usability... yes
checking netinet/in.h presence... yes
checking for netinet/in.h... yes
checking for stdlib.h... (cached) yes
checking for string.h... (cached) yes
checking sys/ioctl.h usability... yes
checking sys/ioctl.h presence... yes
checking for sys/ioctl.h... yes
checking sys/socket.h usability... yes
checking sys/socket.h presence... yes
checking for sys/socket.h... yes
checking syslog.h usability... yes
checking syslog.h presence... yes
checking for syslog.h... yes
checking for unistd.h... (cached) yes
checking net/route.h usability... no
checking net/route.h presence... yes
configure: WARNING: net/route.h: present but cannot be compiled
configure: WARNING: net/route.h:     check for missing prerequisite headers?
configure: WARNING: net/route.h: see the Autoconf documentation
configure: WARNING: net/route.h:     section "Present But Cannot Be Compiled"
configure: WARNING: net/route.h: proceeding with the compiler's result
configure: WARNING:     ## ---------------------------------- ##
configure: WARNING:     ## Report this to troglobit@gmail.com ##
configure: WARNING:     ## ---------------------------------- ##
checking for net/route.h... no
checking sys/param.h usability... yes
checking sys/param.h presence... yes
checking for sys/param.h... yes
checking ifaddrs.h usability... yes
checking ifaddrs.h presence... yes
checking for ifaddrs.h... yes
checking for linux/mroute.h... no
checking for linux/mroute6.h... no
checking linux/sockios.h usability... no
checking linux/sockios.h presence... no
checking for linux/sockios.h... no
checking for netinet/ip_mroute.h... no
checking for netinet6/ip6_mroute.h... yes
checking for IPv6 multicast host support... yes
checking for IPv6 multicast routing support... yes
checking for an ANSI C-conforming const... yes
checking for inline... inline
checking for uint32_t... yes
checking for sun_len member in struct sockaddr_un... yes
checking for vifc_threshold member in struct mif6ctl... no
checking for vifc_rate_limit member in struct mif6ctl... no
checking for pid_t... yes
checking vfork.h usability... no
checking vfork.h presence... no
checking for vfork.h... no
checking for fork... yes
checking for vfork... yes
checking for working fork... yes
checking for working vfork... (cached) yes
checking whether cc needs -traditional... no
checking for stdlib.h... (cached) yes
checking for GNU libc compatible malloc... yes
checking sys/select.h usability... yes
checking sys/select.h presence... yes
checking for sys/select.h... yes
checking for sys/socket.h... (cached) yes
checking types of arguments for select... int,fd_set *,struct timeval *
checking whether setpgrp takes no argument... no
checking for atexit... yes
checking for dup2... yes
checking for memset... yes
checking for select... yes
checking for socket... yes
checking for strchr... yes
checking for strerror... yes
checking for strrchr... yes
checking for asprintf... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating doc/Makefile
config.status: creating src/config.h
config.status: src/config.h is unchanged

[root@wolfje] ~/smcroute-1.99.2# head -30 /usr/include/net/route.h
/*-
 * Copyright (c) 1980, 1986, 1993
 *  The Regents of the University of California.  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.
 * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
 *
 *  @(#)route.h 8.4 (Berkeley) 1/9/95
 * $FreeBSD: release/10.0.0/sys/net/route.h 252184 2013-06-25 00:10:49Z qingli $
[root@wolfje] ~/smcroute-1.99.2# make
[root@wolfje] ~/smcroute-1.99.2# cd src
[root@wolfje] ~/smcroute-1.99.2/src# make
make: "/usr/home/freek/smcroute-1.99.2/src/Makefile" line 59: Missing dependency operator
make: "/usr/home/freek/smcroute-1.99.2/src/Makefile" line 60: Missing dependency operator
make: "/usr/home/freek/smcroute-1.99.2/src/Makefile" line 62: Need an operator
make: "/usr/home/freek/smcroute-1.99.2/src/Makefile" line 63: Need an operator
make: Fatal errors encountered -- cannot continue
make: stopped in /usr/home/freek/smcroute-1.99.2/src
@troglobit
Copy link
Owner

I don't have any FreeBSD installation to play around with at the moment, and the net/route.h issue
could definitely be something that needs looking into.

However, did you try GNU Make when building, or is that BSD PMake?

@macfreek
Copy link
Author

First an obvious question: is FreeBSD supported by smcroute? I thought it was, but I may have been mistaken.

Anyway, this is BSD make. According to the man page, "This make implementation is based on Adam De Boor's pmake program which was written for Sprite at Berkeley.".

It seems there are multiple issues with FreeBSD 10.
1.

configure: WARNING: net/route.h: present but cannot be compiled
configure: WARNING: net/route.h:     check for missing prerequisite headers?
configure: WARNING: net/route.h: see the Autoconf documentation
configure: WARNING: net/route.h:     section "Present But Cannot Be Compiled"
configure: WARNING: net/route.h: proceeding with the compiler's result

I followed the advise at https://www.gnu.org/software/autoconf/manual/autoconf-2.67/html_node/Present-But-Cannot-Be-Compiled.html and changed in configure.ac:

AC_CHECK_HEADERS([arpa/inet.h fcntl.h netinet/in.h stdlib.h string.h \
                  sys/ioctl.h sys/socket.h syslog.h unistd.h \
                  net/route.h sys/param.h ifaddrs.h])

to:

AC_CHECK_HEADERS([arpa/inet.h fcntl.h netinet/in.h stdlib.h string.h \
                  sys/ioctl.h sys/socket.h syslog.h unistd.h \
                  sys/param.h ifaddrs.h])
AC_CHECK_HEADERS([net/route.h], [], [], 
[
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
])

This caused ./configure to recognise net/route.h. Warning: I am by no means a autotools-expert, please check and test before you make changes.

  1. BSD Make still gave the error:
make[1]: "/usr/home/freek/smcroute-1.99.2/src/Makefile" line 59: Missing dependency operator
make[1]: "/usr/home/freek/smcroute-1.99.2/src/Makefile" line 60: Missing dependency operator
make[1]: "/usr/home/freek/smcroute-1.99.2/src/Makefile" line 62: Need an operator
make[1]: "/usr/home/freek/smcroute-1.99.2/src/Makefile" line 63: Need an operator
make[1]: Fatal errors encountered -- cannot continue
make[1]: stopped in /usr/home/freek/smcroute-1.99.2/src
make: *** [all] Error 1

Changing from make to gmake (GNU make) resolved this, but gave another error:

gmake[1]: Entering directory `/usr/home/freek/smcroute-1.99.2/src'
  CC      smcroute.o
In file included from smcroute.c:40:
./mclab.h:131:12: error: use of undeclared identifier 'MAXVIFS'
        uint8 ttl[MAX_MC_VIFS];         /* outgoing VIFs   */
                  ^
./mclab.h:123:21: note: expanded from macro 'MAX_MC_VIFS'
#define MAX_MC_VIFS MAXVIFS             /* from linux/mroute.h */
                    ^
smcroute.c:189:36: error: too few arguments to function call, expected 2, have 0
                    || dup2(0, 2) < 0 || setpgrp() < 0)
                                         ~~~~~~~ ^
/usr/include/unistd.h:456:1: note: 'setpgrp' declared here
int      setpgrp(pid_t _pid, pid_t _pgrp); /* obsoleted by setpgid() */
^
smcroute.c:263:32: error: incomplete definition of type 'struct igmpmsg'
                        if (ip->ip_p == 0 && igmpctl->im_msgtype == IGMPMSG_NOCACHE) {
                                             ~~~~~~~^
smcroute.c:253:11: note: forward declaration of 'struct igmpmsg'
                        struct igmpmsg *igmpctl;
                               ^
smcroute.c:263:48: error: use of undeclared identifier 'IGMPMSG_NOCACHE'
                        if (ip->ip_p == 0 && igmpctl->im_msgtype == IGMPMSG_NOCACHE) {
                                                                    ^
smcroute.c:268:35: error: incomplete definition of type 'struct igmpmsg'
                                mroute.group.s_addr  = igmpctl->im_dst.s_addr;
                                                       ~~~~~~~^
smcroute.c:253:11: note: forward declaration of 'struct igmpmsg'
                        struct igmpmsg *igmpctl;
                               ^
smcroute.c:269:35: error: incomplete definition of type 'struct igmpmsg'
                                mroute.sender.s_addr = igmpctl->im_src.s_addr;
                                                       ~~~~~~~^
smcroute.c:253:11: note: forward declaration of 'struct igmpmsg'
                        struct igmpmsg *igmpctl;
                               ^
smcroute.c:270:35: error: incomplete definition of type 'struct igmpmsg'
                                mroute.inbound       = igmpctl->im_vif;
                                                       ~~~~~~~^
smcroute.c:253:11: note: forward declaration of 'struct igmpmsg'
                        struct igmpmsg *igmpctl;
                               ^

I have not yet investigated the last issue any further.

@troglobit
Copy link
Owner

To respond to your question. Under the care of Debian SMCroute did support FreeBSD. But like any open source project it relies on the input of its contributors.

As the maintainer of multiple multicast routing daemons for UNIX I'm aware of the problems FreeBSD has had with raw sockets, pimd for instance doesn't work at all on FreeBSD. But in FreeBSD 10 it's supposed to be fixed. Again, I haven't had the opportunity to check this myself yet.

Patches are welcome, but you're likely flying on your own at the moment. I wish you the best of luck!

@bombadil
Copy link
Collaborator

Hi,

I did the FreeBSD port some time ago, so I guess that I can contribute a bit to resolve your issue.

To verify your issue I just logged in to a Debian porter box running FreeBSD 9.0 and Debian sid:

micha@asdfasdf:~/smcroute$ uname -a
GNU/kFreeBSD asdfasdf 9.0-2-amd64 #0 Wed Jun  4 12:50:32 UTC 2014 x86_64 amd64 AMD Sempron(tm) Processor 3000+ GNU/kFreeBSD
micha@asdfasdf:~/smcroute$ cat /etc/debian_version 
jessie/sid

But configure still runs on that box without any of the issues mentioned above.

I wonder what this will look like when Debian updates its FreeBSD kernel to FreeBSD 10...

Regarding the suggested fix for your first mentioned issue this looks like a hack to fight a missing include in some of the FreeBSD headers. If this assessment is true I would rather like to see this fixed in the FreeBSD headers, especially as smcroute does build on FreeBSD 9...

Regarding the second issue we need to adress the errors one by one. The first one was that it couldn't find a definition for MAXVIFS, which on my FreeBSD 9 system is located in the include file netinet/ip_mroute.h. At least the missing definition of MAXVIFS matches what your configure run did output earlier:

checking for netinet/ip_mroute.h... no
checking for netinet6/ip6_mroute.h... yes

Are you really trying to build smcroute for use with IPv6 multicast only? If yes we probably need to add some more macro conditionals to the code to get it built on IPv6 only systems too...

Best regards,
Micha

@troglobit
Copy link
Owner

OK, I've got a FreeBSD 10 installation up and running now. I needed it for troglobit/pimd#23 as well ...

I see quite a bit of problems ... introduced by me, blindly focusing too much on Linux. Fixing.

troglobit added a commit that referenced this issue Sep 21, 2014
FreeBSD fixes
- net/route.h needs sys/socket.h (struct sockaddr)
- netinet/ip_mroute.h needs sys/types.h (u_long et consortes)

Fixes part of smcroute issue #5

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
troglobit added a commit that referenced this issue Sep 21, 2014
…eeBSD

- Refactor dep file generation using fancy new GCC feature
- Remove ifneq's around -include, not needed now

Fixes part of smcroute issue #5

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
troglobit added a commit that referenced this issue Sep 21, 2014
- Fix comment-within-comment Linux/*BSD --> Linux and *BSD
- Fix 'struct vif' definition --> struct { .. } vif_list[]

Fixes part of smcroute issue #5

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
troglobit added a commit that referenced this issue Sep 21, 2014
The System V calling convention for setpgrp() is not available on
FreeBSD, replace with equivalent setpgid(0, 0).

Also, fix missing return value in read_mroute6_socket().

Fixes part of smcroute issue #5

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
@troglobit
Copy link
Owner

@macfreek If at all possible, could you try the latest master?

@macfreek
Copy link
Author

@troglobit Thanks a lot! I was able to compile it, but I am away from home this week, and can't actually check if the output is a usable program :). I'll do so next weekend.

There are some minor issues with the Makefile, which may have to do with difference between GNU make and BSD make:

  • BSF make without any argument returns immediately, without doing anything. GNU make runs the 'all' recipe (which is the first). I'm not sure if this is 'as designed' for the FreeBSD make. I find it annoying.
  • RM is not defined in BSD make. 'make clean' executes '$(RM) route.h ' which in effect tries to execute route.h. Jolly good fun there too.

@bombadil It seems that API for raw sockets have been changed in FreeBSD 10, and will again change for FreeBSD 11: http://lists.freebsd.org/pipermail/freebsd-net/2014-January/037512.html. My first hunch was that this was causing my problems, but it seems unrelated (as far as I can tell from the commits).

PS: It is annoying that the link on the scmroute github page named "Download ZIP" downloads an old version. I should learn to recognise the hashes from each other. :)

@troglobit
Copy link
Owner

@macfreek Great news, thank you so much for testing! :)

I too noticed the remaining PMake issues that you summarized. Very annoying. Would be great to have them fixed as well. Patches are most welcome!

I've just come back from a session with patching up the FreeBSD 10 kernel, investigating the SOCK_RAW problems that pimd has had. There is no problems for SMCRoute since it does not compose or interpret any IP header, where FreeBSD raw sockets deviate from the rest of the *BSD and Linux.

@macfreek
Copy link
Author

About the Makefile: the line .EXPORT_ALL_VARIABLES: is not recognised as special by PMake. So (1) no variables are exported when make is recursively called for the src or doc directory. And (2) since this is the first line, a make without arguments executes the .EXPORT_ALL_VARIABLES rule instead of the all rule.

There seem 3 solutions. I'm not familiar enough with Makefiles to know what is most common, so I'll ask here first before making a patch:

  1. Explicitly export all variables
  2. Add the same preamble with variable settings to each Makefile
  3. Merge all Makefiles in one Makefile

Links:

@macfreek
Copy link
Author

I could compile smcroute without problems, but unfortunately, couldn't yet make it run.

Unfortunately, this can be either caused by my lack of understanding of multicast, a misconfiguration of my FreeBSD system, or even a bug in smcroute.

First of all, FreeBSD by default does not support multicast. In the FreeBSD forum, the suggestion is to compile the kernel with the support, but I simply loaded it using kldload ip_mroute.ko and kldload ip6_mroute.ko. I suspect this is sufficient.

Without ip_mroute.ko nor ip6_mroute.ko loaded:

# smcroute -d -n
Failed initializing IPv4 multicast routing API. Error 45: Operation not supported
Failed initializing IPv6 multicast routing API. Error 45: Operation not supported
Kernel does not support multicast routing. Error 42: Protocol not available

With ip_mroute.ko loaded, but not ip6_mroute.ko:

# smcroute -d -n
Failed initializing IPv6 multicast routing API. Error 45: Operation not supported
UDP socket connect. Error 49: Can't assign requested address

With both ip_mroute.ko and ip6_mroute.ko loaded:

# smcroute -d -n
Failed enabling IPv6 multicast forwarding. Error 2: No such file or directory

Right now I'm only interested in IPv4 support. My config file is:

mgroup from em3 group 224.0.251.124
mroute from em3 group 224.0.251.124 to em1
mgroup from em3 group 224.0.251.125
mroute from em3 group 224.0.251.125 to em1

My questions are: (1) Is it possible to suppress the IPv6 warning/error? (2) What could be the cause of the Can't assign requested address error?

troglobit added a commit that referenced this issue Sep 28, 2014
The IPv6 multicast routing proc setting does not exist outside Linux,
conditionalize it using #ifdef __linux__ (compiler built-in define).

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
troglobit added a commit that referenced this issue Sep 28, 2014
For some reason the legacy code to open a local kernel socket for IPv4
group join/leave (IP_ADD/DROP_MEMBERSHOP) had a completely useless
connect() statement in it.  It's not needed to do setsockopt() and
FreeBSD 10 fails on it -- drop code and simplify.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
@troglobit
Copy link
Owner

Well spotted, more Linux anachronisms and bogus legacy code!

I've now finally tested the latest code on my FreeBSD box and from what I can see it now works! :)

Great tip there to kldload ip_mroute.ko, did not know you could do that. I've always had to
recompile my *BSD kernels. Thanks 👍

@troglobit troglobit changed the title Problem with route.h on FreeBSD 10.0 Problem building and running SMCRoute on FreeBSD Sep 28, 2014
troglobit added a commit that referenced this issue Sep 28, 2014
1) This project is too small to motivate several subdirectories
2) With a simpler Makefile we can target BSD PMake with less effort

This commit is inspired by the discussions in issue #5

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
@troglobit
Copy link
Owner

Also, I've just pushed commit 0171caf that flattens the directory structure and
merged all Makefiles. On my FreeBSD box SMCRoute can now be built using
the standard PMake. Enjoy! 🎁 😏

Let me know if this helps for you, then we can release this as SMCRoute 2.0 ☺️

@macfreek
Copy link
Author

@troglobit You are awesome!

The program seems to do what it is supposed to do. I run into a minor install issue, and unfortunately, it seems that smcroute is not the solution to my problem after all (told you I was new to multicast).

As for the minor install issue, for whatever reason, the unzip that comes with FreeBSD does not seems to extract symlinks:

# unzip smcroute-master.zip
Archive:  smcroute-master.zip
d smcroute-master
 extracting: smcroute-master/.gitignore
 extracting: smcroute-master/.travis.yml
 extracting: smcroute-master/AUTHORS
 extracting: smcroute-master/COPYING
unzip: skipping non-regular entry 'smcroute-master/ChangeLog'
 extracting: smcroute-master/ChangeLog.md
 extracting: smcroute-master/Makefile.in
unzip: skipping non-regular entry 'smcroute-master/README'
 extracting: smcroute-master/README.md
 extracting: smcroute-master/TODO
 ...

Right now make install drops the ball when the symlink is not created:

# make install
install: README: No such file or directory
*** Error code 71

Stop.
make: stopped in /usr/home/freek/smcroute-master

To be honest, I'm not sure if this should be your problem (frankly, the only reason why I didn't install the GNU version is because this machine is my (home) router and I like to keep it bare). At least you know.

The easiest solution is to just add a rule in the Make file for these two files, and have install depend on these files:

README:
    ln -s README.md README

ChangeLog:
    ln -s ChangeLog.md ChangeLog

install: README ChangeLog
    ....

@troglobit
Copy link
Owner

Ah, yeah I just recently moved to ChangeLog.md and README.md on behalf of GitHub.
The best way is probably to create some custom dist-rule that installs them on target w/o .md ...
Thanks for the heads-up, my bad!

So, what problem was it you were trying to solve? Some people like dynamic multicast routing,
like mrouted/pimd (which I also maintain ;) whereas others like the igmp-proxy program. Or,
you might have needed a GRE or OpenVPN Layer-2 tunnel to forward multicast over?

troglobit added a commit that referenced this issue Sep 28, 2014
…d system

Initial conversion from lightweight configure with homegrown Makefile.in
to using full configure + Makefile.am -- heads up, files may be missing
from `make dist` or `make install`!

This commit should also fix the last issues with install/unzip mentioned
in issue #5 -- resulting README and ChangeLog are now copied to archive.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
@bombadil
Copy link
Collaborator

Just a minor additional data point: While smcroute 1.99.2 fails to build on Debian architectures kfreebsd-amd64 and kfreebsd-i386, the current git master (as of commit 7241100) doesn't fail to build anymore. Well done!

@troglobit
Copy link
Owner

That's good to hear @bombadil but it wouldn't have happened if it hadn't been for @macfreek -- thank you! 😃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants