IPv6 NDS: source address selection in NA

I'm experiencing some inconsistency in the source address selection implementation for IPv6 Network Discovery Protocol's Neighbor Advertisement message.

According to the article http://www.freebsd.org/doc/en/books/developers-handbook/ipv6.html#ipv6-sas:
If there is an address assigned to the outgoing interface (which is usually determined by looking up the routing table) that has the same scope as the destination address, the address is used.
There are some cases where we do not use the above rule. ... example is source address for Neighbor Advertisement. Under the spec (RFC2461 7.2.2) NA's source should be the target address of the corresponding NS's target. In this case we follow the spec rather than the above longest-match rule.

My operating system version is: FreeBSD 9.1-RELEASE #0 r243825: Tue Dec 4 09:23:10 UTC 2012 root@farrell.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC amd64

My network configuration is:
Code:
defaultrouter="188.120.239.254"
ifconfig_vtnet0="inet 188.120.235.252 netmask 255.255.240.0" 
ifconfig_vtnet0_ipv6="inet6 2a01:230:2::792 prefixlen 64"
ipv6_defaultrouter="2a01:230:2::1"
Code:
vtnet0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	options=c07bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,LINKSTATE>
	ether 52:54:00:ba:e0:d6
	inet 188.120.235.252 netmask 0xfffff000 broadcast 188.120.239.255
	inet6 fe80::5054:ff:feba:e0d6%vtnet0 prefixlen 64 scopeid 0x2 
	inet6 2a01:230:2::792 prefixlen 64 
	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
	media: Ethernet 1000baseT <full-duplex>
	status: active
Destination                       Gateway                       Flags      Netif Expire
::/96                             ::1                           UGRS        lo0 =>
default                           2a01:230:2::1                 UGS      vtnet0
::1                               link#3                        UH          lo0
::ffff:0.0.0.0/96                 ::1                           UGRS        lo0
2a01:230:2::/64                   link#2                        U        vtnet0
2a01:230:2::792                   link#2                        UHS         lo0
fe80::/10                         ::1                           UGRS        lo0
fe80::%vtnet0/64                  link#2                        U        vtnet0
fe80::5054:ff:feba:e0d6%vtnet0    link#2                        UHS         lo0
fe80::%lo0/64                     link#3                        U           lo0
fe80::1%lo0                       link#3                        UHS         lo0
ff01::%vtnet0/32                  fe80::5054:ff:feba:e0d6%vtnet0 U        vtnet0
ff01::%lo0/32                     ::1                           U           lo0
ff02::/16                         ::1                           UGRS        lo0
ff02::%vtnet0/32                  fe80::5054:ff:feba:e0d6%vtnet0 U        vtnet0
ff02::%lo0/32                     ::1                           U           lo0

When the ICMP6 Neighbor Solicitation message is received, the Neighbor Advertisement message is sent using source address determined by the routing table and FreeBSD's "implementation defined" behavior (selecting the source address in the same scope as one in the sender address) ignoring the exception for the ICMP6 NA message (where source address should be the same as the Target address in the message).
Code:
15:46:06.267985 00:25:84:01:9e:40 > 33:33:ff:00:07:92, ethertype IPv6 (0x86dd), length 86: (class 0xe0, hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::225:84ff:fe01:9e40 > ff02::1:ff00:792: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has 2a01:230:2::792
	  source link-address option (1), length 8 (1): 00:25:84:01:9e:40
	    0x0000:  0025 8401 9e40
15:46:06.268007 52:54:00:ba:e0:d6 > 00:25:84:01:9e:40, ethertype IPv6 (0x86dd), length 86: (hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::5054:ff:feba:e0d6 > fe80::225:84ff:fe01:9e40: [icmp6 sum ok] ICMP6, neighbor advertisement, length 32, tgt is 2a01:230:2::792, Flags [solicited, override]
	  destination link-address option (2), length 8 (1): 52:54:00:ba:e0:d6
	    0x0000:  5254 00ba e0d6

When I remove link-local address then the source address for the ICMP6 NA messages is selected correctly.
Code:
vtnet0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	options=c07bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,LINKSTATE>
	ether 52:54:00:ba:e0:d6
	inet 188.120.235.252 netmask 0xfffff000 broadcast 188.120.239.255
	inet6 2a01:230:2::792 prefixlen 64 
	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
	media: Ethernet 1000baseT <full-duplex>
	status: active
Destination                       Gateway                       Flags      Netif Expire
::/96                             ::1                           UGRS        lo0 =>
default                           2a01:230:2::1                 UGS      vtnet0
::1                               link#3                        UH          lo0
::ffff:0.0.0.0/96                 ::1                           UGRS        lo0
2a01:230:2::/64                   link#2                        U        vtnet0
2a01:230:2::792                   link#2                        UHS         lo0
fe80::/10                         ::1                           UGRS        lo0
fe80::%vtnet0/64                  link#2                        U        vtnet0
fe80::%lo0/64                     link#3                        U           lo0
fe80::1%lo0                       link#3                        UHS         lo0
ff01::%vtnet0/32                  2a01:230:2::792               U        vtnet0
ff01::%lo0/32                     ::1                           U           lo0
ff02::/16                         ::1                           UGRS        lo0
ff02::%vtnet0/32                  2a01:230:2::792               U        vtnet0
ff02::%lo0/32                     ::1                           U           lo0
Code:
16:02:18.375236 00:25:84:01:9e:40 > 33:33:ff:00:07:92, ethertype IPv6 (0x86dd), length 86: (class 0xe0, hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::225:84ff:fe01:9e40 > ff02::1:ff00:792: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has 2a01:230:2::792
	  source link-address option (1), length 8 (1): 00:25:84:01:9e:40
	    0x0000:  0025 8401 9e40
16:02:18.375263 52:54:00:ba:e0:d6 > 00:25:84:01:9e:40, ethertype IPv6 (0x86dd), length 86: (hlim 255, next-header ICMPv6 (58) payload length: 32) 2a01:230:2::792 > fe80::225:84ff:fe01:9e40: [icmp6 sum ok] ICMP6, neighbor advertisement, length 32, tgt is 2a01:230:2::792, Flags [solicited, override]
	  destination link-address option (2), length 8 (1): 52:54:00:ba:e0:d6
	    0x0000:  5254 00ba e0d6
16:04:54.818773 00:25:84:01:9e:40 > 52:54:00:ba:e0:d6, ethertype IPv6 (0x86dd), length 86: (class 0xe0, hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::225:84ff:fe01:9e40 > 2a01:230:2::792: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has 2a01:230:2::792
	  source link-address option (1), length 8 (1): 00:25:84:01:9e:40
	    0x0000:  0025 8401 9e40
16:04:54.818793 52:54:00:ba:e0:d6 > 00:25:84:01:9e:40, ethertype IPv6 (0x86dd), length 78: (hlim 255, next-header ICMPv6 (58) payload length: 24) 2a01:230:2::792 > fe80::225:84ff:fe01:9e40: [icmp6 sum ok] ICMP6, neighbor advertisement, length 24, tgt is 2a01:230:2::792, Flags [solicited]

It is considered that removing link-local IPv6 addresses is unwanted approach. How may I change the Gateway entries in the routing table for ff01::%vtnet0/32 and ff02::%vtnet0/32 destinations using the rc.conf or trigger the "correct workaround" for ICMP6 NA messages using sysctl? Is there another approach?
 
A solution (ugly, for now)

/boot/loader.conf:
Code:
net.inet6.ip6.auto_linklocal=0

/etc/rc.conf:
Code:
ipv6_static_routes=linklocal
ipv6_route_linklocal="fe80::%vtnet0/64 -iface vtnet0"

An additional static route is needed because the router is sending NDP messages from its link-local address and without auto_linklocal that route will not be installed by default.
 
Back
Top