Fixing nss-mdns for IPv6 linklocal scoped addresses : Différence entre versions
(Page créée avec « {{2A}} {{Informatique}} == The configuration == We are running FreeBSD 8.2-RELEASE with GENERIC kernel [http://www.freshports.org/dns/nss_mdns/ nss_mdns] is a port of [htt... ») |
(Still ok for new releases) |
||
(6 révisions intermédiaires par le même utilisateur non affichées) | |||
Ligne 3 : | Ligne 3 : | ||
== The configuration == | == The configuration == | ||
− | + | Running FreeBSD 8.2-RELEASE with GENERIC kernel. | |
+ | |||
+ | Update: still works on 9 and 9.1 | ||
[http://www.freshports.org/dns/nss_mdns/ nss_mdns] is a port of [http://0pointer.de/lennart/projects/nss-mdns/ nss-mdns] for FreeBSD. It adds support for mDNS address resolution system-wide through the use of a name service switch plugin. Here is the simplest configuration: | [http://www.freshports.org/dns/nss_mdns/ nss_mdns] is a port of [http://0pointer.de/lennart/projects/nss-mdns/ nss-mdns] for FreeBSD. It adds support for mDNS address resolution system-wide through the use of a name service switch plugin. Here is the simplest configuration: | ||
Ligne 13 : | Ligne 15 : | ||
# make install | # make install | ||
and make appropriate configuration changes | and make appropriate configuration changes | ||
+ | * in /usr/local/etc/avahi/avahi-daemon.conf | ||
+ | use-ipv6=yes | ||
* in /etc/rc.conf | * in /etc/rc.conf | ||
− | + | dbus_enable="YES" | |
− | + | avahi_daemon_enable="YES" | |
* in /etc/nsswitch.conf | * in /etc/nsswitch.conf | ||
− | + | hosts: files mdns dns | |
== The problem == | == The problem == | ||
IPv6 is configured on all interfaces and no global prefix is defined. We only have linklocal addresses. | IPv6 is configured on all interfaces and no global prefix is defined. We only have linklocal addresses. | ||
− | mDNS resolution works fine, but ping6 fails miserably, even when specifying the outgoing interface. | + | mDNS resolution works fine, but <tt>ping6</tt> fails miserably, even when specifying the outgoing interface. |
bsd1# RES_OPTIONS=inet6 getent hosts bsd2.local | bsd1# RES_OPTIONS=inet6 getent hosts bsd2.local | ||
Ligne 31 : | Ligne 35 : | ||
ping6: UDP connect: Device not configured | ping6: UDP connect: Device not configured | ||
− | + | This is not a routing problem, we would have <tt>Network is unreachable</tt> in this case, but an interface / scope id problem. | |
== The bug == | == The bug == | ||
− | == The fix == | + | Even option <tt>-I</tt> in <tt>ping6</tt> would not change anything. And when tracing down the scope id used, it turned out to be 673273636! Obviously, there is no such device configured. (cf. [http://www.freebsd.org/cgi/cvsweb.cgi/src/sbin/ping6/ping6.c?annotate=1.37.2.2.4.1 ping6.c:966] <tt>src.sin6_scope_id</tt> and <tt>dst.sin6_scope_id</tt>1) |
+ | |||
+ | The problem is in <tt>bsdnss.c</tt> where the address is copied in <tt>sin6_addr</tt> with a way to long length, <tt>ai->ai_addrlen</tt>, where it should be <tt>sizeof(struct in6_addr)</tt>. | ||
+ | |||
+ | == The quick fix and dirty enhancement == | ||
+ | |||
+ | With this fixed, no more device not configured, but still a network unreachable. Although, using <tt>ping6 -I</tt> works nicely now. | ||
+ | But it would be great to have the scope id filled in the data structure, which is possible at low cost, since avahi returns this information, the second field in the reply below. | ||
+ | |||
+ | bsd1# nc -U /var/run/avahi-daemon/socket | ||
+ | RESOLVE-HOSTNAME-IPV6 bsd2.local | ||
+ | + 2 1 bsd2.local fe80::a00:27ff:fef4:c55d | ||
+ | |||
+ | A simple and dirty patch in <tt>query.h</tt> to add the <tt>scope_id</tt> to the data structure (we can do that safely, even if it is very ugly, because the buffer mallocated at <tt>nss.c:307</tt> is huge), <tt>avahi.c</tt> to fill this info, and <tt>bsdnss.c</tt> to fill the <tt>struct sockaddr_in6</tt> when we have a linklocal address, and that's it. | ||
+ | Things work nicely now: | ||
+ | |||
+ | # ping6 bsd2.local | ||
+ | PING6(56=40+8+8 bytes) fe80::a00:27ff:fe9d:5a8f%em1 --> fe80::a00:27ff:fef4:c55d%em1 | ||
+ | 16 bytes from fe80::a00:27ff:fef4:c55d%em1, icmp_seq=0 hlim=64 time=0.329 ms | ||
+ | 16 bytes from fe80::a00:27ff:fef4:c55d%em1, icmp_seq=1 hlim=64 time=0.657 ms | ||
+ | ^C | ||
+ | --- bsd2.local ping6 statistics --- | ||
+ | 2 packets transmitted, 2 packets received, 0.0% packet loss | ||
+ | round-trip min/avg/max/std-dev = 0.329/0.493/0.657/0.164 ms | ||
+ | |||
+ | == The patch == | ||
+ | |||
+ | This fix and enhancement were made only for the FreeBSD port, based on <tt>release-0.10</tt>. | ||
+ | |||
+ | * [ <tt>git diff</tt> patch file] on branch <tt>release-0.10</tt> (not needed if you use the port) | ||
+ | ** <tt>git://git.0pointer.de/nss-mdns.git</tt> | ||
+ | * [[Media:Patch-src_AAA-nss-mdns-linklocal.c|patch-src_AAA-nss-mdns-linklocal.c]] patch file for the FreeBSD port: this patch was made so that it can be applied before the port patches without problems (hence the stupid name) | ||
+ | ** copy this file in <tt>/usr/ports/dns/nss_mdns/files</tt> (then change back the capital P to p, mediawiki does that) | ||
+ | ** <tt>make install</tt> (<tt>deinstall</tt> before if needed) | ||
+ | |||
+ | == References == | ||
+ | |||
+ | # [http://www.freebsd.org/releases/8.2R/announce.html FreeBSD 8.2] | ||
+ | # [http://www.freebsd.org/doc/handbook/network-ipv6.html IPv6] on FreeBSD | ||
+ | # [http://avahi.org/ avahi] | ||
+ | # [http://0pointer.de/lennart/projects/nss-mdns/ nss-mdns] | ||
+ | # [http://www.freshports.org/dns/nss_mdns/ nss_mdns] port | ||
+ | # [http://www.freebsd.org/cgi/cvsweb.cgi/src/sbin/ping6/ ping6] source code | ||
+ | # [http://www.endeavoursofanengineer.com/blog/2010/05/08/installing-avahi-on-freebsd-2/ Installing avahi on FreeBSD] | ||
+ | # [http://myfreebsd.homeunix.net/hints_n_kinks/local-ports.html#LOCAL-PATCHES Local Patches and Ports] |
Version actuelle en date du 19 septembre 2013 à 12:42
Sommaire
The configuration
Running FreeBSD 8.2-RELEASE with GENERIC kernel.
Update: still works on 9 and 9.1
nss_mdns is a port of nss-mdns for FreeBSD. It adds support for mDNS address resolution system-wide through the use of a name service switch plugin. Here is the simplest configuration:
# cd /usr/ports/net/avahi # make install # cd /usr/ports/dns/nss_mdns # make install
and make appropriate configuration changes
- in /usr/local/etc/avahi/avahi-daemon.conf
use-ipv6=yes
- in /etc/rc.conf
dbus_enable="YES" avahi_daemon_enable="YES"
- in /etc/nsswitch.conf
hosts: files mdns dns
The problem
IPv6 is configured on all interfaces and no global prefix is defined. We only have linklocal addresses. mDNS resolution works fine, but ping6 fails miserably, even when specifying the outgoing interface.
bsd1# RES_OPTIONS=inet6 getent hosts bsd2.local fe80::a00:27ff:fef4:c55d bsd2.local bsd1# ping6 bsd2.local ping6: UDP connect: Device not configured bsd1# ping6 -I em0 bsd2.local ping6: UDP connect: Device not configured
This is not a routing problem, we would have Network is unreachable in this case, but an interface / scope id problem.
The bug
Even option -I in ping6 would not change anything. And when tracing down the scope id used, it turned out to be 673273636! Obviously, there is no such device configured. (cf. ping6.c:966 src.sin6_scope_id and dst.sin6_scope_id1)
The problem is in bsdnss.c where the address is copied in sin6_addr with a way to long length, ai->ai_addrlen, where it should be sizeof(struct in6_addr).
The quick fix and dirty enhancement
With this fixed, no more device not configured, but still a network unreachable. Although, using ping6 -I works nicely now. But it would be great to have the scope id filled in the data structure, which is possible at low cost, since avahi returns this information, the second field in the reply below.
bsd1# nc -U /var/run/avahi-daemon/socket RESOLVE-HOSTNAME-IPV6 bsd2.local + 2 1 bsd2.local fe80::a00:27ff:fef4:c55d
A simple and dirty patch in query.h to add the scope_id to the data structure (we can do that safely, even if it is very ugly, because the buffer mallocated at nss.c:307 is huge), avahi.c to fill this info, and bsdnss.c to fill the struct sockaddr_in6 when we have a linklocal address, and that's it. Things work nicely now:
# ping6 bsd2.local PING6(56=40+8+8 bytes) fe80::a00:27ff:fe9d:5a8f%em1 --> fe80::a00:27ff:fef4:c55d%em1 16 bytes from fe80::a00:27ff:fef4:c55d%em1, icmp_seq=0 hlim=64 time=0.329 ms 16 bytes from fe80::a00:27ff:fef4:c55d%em1, icmp_seq=1 hlim=64 time=0.657 ms ^C --- bsd2.local ping6 statistics --- 2 packets transmitted, 2 packets received, 0.0% packet loss round-trip min/avg/max/std-dev = 0.329/0.493/0.657/0.164 ms
The patch
This fix and enhancement were made only for the FreeBSD port, based on release-0.10.
- [ git diff patch file] on branch release-0.10 (not needed if you use the port)
- patch-src_AAA-nss-mdns-linklocal.c patch file for the FreeBSD port: this patch was made so that it can be applied before the port patches without problems (hence the stupid name)
- copy this file in /usr/ports/dns/nss_mdns/files (then change back the capital P to p, mediawiki does that)
- make install (deinstall before if needed)
References
- FreeBSD 8.2
- IPv6 on FreeBSD
- avahi
- nss-mdns
- nss_mdns port
- ping6 source code
- Installing avahi on FreeBSD
- Local Patches and Ports