[radvd-devel-l] radvd on freetz (Fritzbox mod) - radvd[1865]: setsockopt(IPV6_RECVPKTINFO): Protocol not available

Pekka Savola pekkas at netcore.fi
Fri Jan 16 16:58:59 EST 2009


Hi,

On Thu, 15 Jan 2009, Paul Oranje wrote:
> The following patch has solved the problem on the Fritzbox 7170 with
> kernel 2.6.13 and uclibc 0.9.29:
...

I see better now, thanks for persistence.

I dislike this approach a bit because you're checking the kernel 
version libc has been compiled with.  So this doesn't actually help in 
all cases.  And looking googling at this, some folks also seem to 
be having a problem like this in other contexts.

The optimal solution would obviously be updating the kernel, but I 
guess this is not feasible.  The kernel and uclibc setsockopt 
interfaces are not in sync, and that's causing your problems.

It's possible to workaround this in the application.  I suppose this 
is something I'll need to consider.

Can you try the attached patch?  You will need to 'autoreconf' to 
regenerate the configure and config.h.in files.

-- 
Pekka Savola                 "You each name yourselves king, yet the
Netcore Oy                    kingdom bleeds."
Systems. Networks. Security. -- George R.R. Martin: A Clash of Kings
-------------- next part --------------
diff -u radvd-1.2/configure.in radvd-1.2.mod2/configure.in
--- radvd-1.2/configure.in	2008-10-14 16:10:11.000000000 +0300
+++ radvd-1.2.mod2/configure.in	2009-01-16 23:50:04.000000000 +0200
@@ -143,6 +143,51 @@
 1, [whether struct in6_addr has u6_addrXX and defines s6_addrXX])],
 AC_MSG_RESULT(no))
 
+dnl checks if libc and kernel are mismatched and we need a workaround
+
+AC_MSG_CHECKING(whether IPV6_RECVPKTINFO is defined and works with kernel)
+AC_TRY_RUN([
+#include <netinet/in.h>
+#include <sys/errno.h>
+
+int main(void) {
+ int sock, err, val=1;
+ sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ if (socket < 0) { 
+   return 0;
+ }
+ err = setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val, sizeof(val));
+ if (err < 0) {
+   if (errno == ENOPROTOOPT)
+     return 1;
+ }
+ return 0;
+}],
+AC_MSG_RESULT(yes),
+[AC_MSG_RESULT(no); AC_DEFINE(HAVE_BROKEN_IPV6_RECVPKTINFO, 1,
+whether IPV6_RECVPKTINFO is defined and works with kernel)])
+
+AC_MSG_CHECKING(whether IPV6_RECVHOPLIMIT is defined and works with kernel)
+AC_TRY_RUN([
+#include <netinet/in.h>
+#include <sys/errno.h>
+
+int main(void) {
+ int sock, err, val=1;
+ sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ if (socket < 0) { 
+   return 0;
+ }
+ err = setsockopt(sock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &val, sizeof(val));
+ if (err < 0) {
+   if (errno == ENOPROTOOPT)
+     return 1;
+ }
+ return 0;
+}], AC_MSG_RESULT(yes),
+[AC_MSG_RESULT(no); AC_DEFINE(HAVE_BROKEN_IPV6_RECVHOPLIMIT, 1,
+whether IPV6_RECVHOPLIMIT is defined and works with kernel)])
+
 dnl Checks for library functions.
 AC_CHECK_FUNCS(getopt_long)
 
diff -u radvd-1.2/radvd.h radvd-1.2.mod2/radvd.h
--- radvd-1.2/radvd.h	2008-01-24 12:10:18.000000000 +0200
+++ radvd-1.2.mod2/radvd.h	2009-01-16 23:53:21.000000000 +0200
@@ -235,4 +235,15 @@
 int privsep_interface_reachtime(const char *iface, uint32_t rtime);
 int privsep_interface_retranstimer(const char *iface, uint32_t rettimer);
 
+/* compat hacks in case libc and kernel get out of sync */
+/* these are placed here because they're needed in all of socket.c, recv.c and send.c */
+#if defined HAVE_BROKEN_IPV6_RECVHOPLIMIT && defined IPV6_2292HOPLIMIT
+# undef IPV6_RECVHOPLIMIT
+# define IPV6_RECVHOPLIMIT IPV6_2292HOPLIMIT
+#endif
+#if defined HAVE_BROKEN_IPV6_RECVPKTINFO && defined IPV6_2292PKTINFO
+# undef IPV6_RECVPKTINFO
+# define IPV6_RECVPKTINFO IPV6_2292PKTINFO
+#endif
+
 #endif


More information about the radvd-devel-l mailing list