IPv6 addess autoconfiguration vs bridged interface on Linux
Shadow Hawkins on Friday, 30 January 2009 23:10:05
I have a problem somewhere between bridged network interface and IPv6 address configuration.
quince ~ # uname -s -r
Linux 2.6.28
quince ~ # emerge --search bridge-utils
* net-misc/bridge-utils
Latest version available: 1.4
Latest version installed: 1.4
When the system is starting up, first the eth0 interface is being brought up. It gets autoconfigured over ipv6, gets an address and a route.
quince ~ # ip -6 addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000
inet6 2001:123:456:0:21e:ecff:fe8b:d0be/64 scope global tentative dynamic
valid_lft 2592000sec preferred_lft 604800sec
inet6 fe80::21e:ecff:fe8b:d0be/64 scope link
valid_lft forever preferred_lft forever
quince ~ # ip -6 route show dev eth0
2001:123:456::/64 proto kernel metric 256 expires 2592160sec mtu 1500 advmss 1440 hoplimit 4294967295
fe80::/64 proto kernel metric 256 mtu 1500 advmss 1440 hoplimit 4294967295
ff00::/8 metric 256 mtu 1500 advmss 1440 hoplimit 4294967295
default via fe80::200:ff:fe00:0 proto kernel metric 1024 expires 1798sec mtu 1500 advmss 1440 hoplimit 64
So far so good. Next, a bridge is being created:
quince ~ # brctl show
bridge namebridge idSTP enabledinterfaces
br08000.001eec8bd0beyeseth0
vbox0
vbox1
The bridge gets its own IPv6 address, and its own route:
quince ~ # ip -6 a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qlen 1000
inet6 2001:123:456:0:21e:ecff:fe8b:d0be/64 scope global dynamic
valid_lft 2590336sec preferred_lft 603136sec
inet6 fe80::21e:ecff:fe8b:d0be/64 scope link
valid_lft forever preferred_lft forever
7: vbox0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qlen 500
inet6 fe80::c835:acff:fe78:9059/64 scope link
valid_lft forever preferred_lft forever
8: vbox1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qlen 500
inet6 fe80::f8de:6fff:feef:f82b/64 scope link
valid_lft forever preferred_lft forever
11: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500
inet6 2001:123:456:0:21e:ecff:fe8b:d0be/64 scope global dynamic
valid_lft 2591411sec preferred_lft 604211sec
inet6 fe80::21e:ecff:fe8b:d0be/64 scope link
valid_lft forever preferred_lft forever
quince ~ # ip -6 r s
2001:123:456::/64 dev eth0 proto kernel metric 256 expires 2590494sec mtu 1500 advmss 1440 hoplimit 4294967295
2001:123:456::/64 dev br0 proto kernel metric 256 expires 2591569sec mtu 1500 advmss 1440 hoplimit 4294967295
fe80::/64 dev vbox0 proto kernel metric 256 mtu 1500 advmss 1440 hoplimit 4294967295
fe80::/64 dev vbox1 proto kernel metric 256 mtu 1500 advmss 1440 hoplimit 4294967295
fe80::/64 dev eth0 proto kernel metric 256 mtu 1500 advmss 1440 hoplimit 4294967295
fe80::/64 dev br0 proto kernel metric 256 mtu 1500 advmss 1440 hoplimit 4294967295
ff00::/8 dev vbox0 metric 256 mtu 1500 advmss 1440 hoplimit 4294967295
ff00::/8 dev vbox1 metric 256 mtu 1500 advmss 1440 hoplimit 4294967295
ff00::/8 dev eth0 metric 256 mtu 1500 advmss 1440 hoplimit 4294967295
ff00::/8 dev br0 metric 256 mtu 1500 advmss 1440 hoplimit 4294967295
default via fe80::200:ff:fe00:0 dev eth0 proto kernel metric 1024 expires 132sec mtu 1500 advmss 1440 hoplimit 64
default via fe80::200:ff:fe00:0 dev br0 proto kernel metric 1024 expires 1207sec mtu 1500 advmss 1440 hoplimit 64
Look at the routes:
2001:123:456::/64 dev eth0 proto kernel metric 256 expires 2592298sec mtu 1500 advmss 1440 hoplimit 4294967295
2001:123:456::/64 dev br0 proto kernel metric 256 expires 2592303sec mtu 1500 advmss 1440 hoplimit 4294967295
Now there are two. When trying to ping the router from the affected host:
quince ~ # tcpdump -v -i eth0 icmp6
tcpdump: WARNING: eth0: no IPv4 address assigned
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
21:00:25.600789 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) quince.home.blizinski.pl > ff02::1:ff00:1: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has openwrt.home.blizinski.pl
source link-address option (1), length 8 (1): 00:1e:ec:8b:d0:be
21:00:25.601567 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) openwrt.home.blizinski.pl > quince.home.blizinski.pl: [icmp6 sum ok] ICMP6, neighbor advertisement, length 32, tgt is openwrt.home.blizinski.pl, Flags [router, solicited, override]
destination link-address option (2), length 8 (1): 00:1e:e5:5b:13:83
root@OpenWrt:~# tcpdump -v icmp6
tcpdump: listening on br-lan, link-type EN10MB (Ethernet), capture size 96 bytes
21:00:27.241562 IP6 (hlim 255, next-header: ICMPv6 (58), length: 32) quince.home.blizinski.pl > ff02::1:ff00:1: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has openwrt.home.blizinski.pl
source link-address option (1), length 8 (1): 00:1e:ec:8b:d0:be
21:00:27.242094 IP6 (hlim 255, next-header: ICMPv6 (58), length: 32) openwrt.home.blizinski.pl > quince.home.blizinski.pl: [icmp6 sum ok] ICMP6, neighbor advertisement, length 32, tgt is openwrt.home.blizinski.pl, Flags [router, solicited, override]
destination link-address option (2), length 8 (1): 00:1e:e5:5b:13:83
Let's reformat it a bit. A packet goes out from quince:
21:00:25.600789 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32)
quince.home.blizinski.pl > ff02::1:ff00:1: [icmp6 sum ok] ICMP6,
neighbor solicitation, length 32, who has openwrt.home.blizinski.pl
source link-address option (1), length 8 (1): 00:1e:ec:8b:d0:be
And arrives at openwrt:
21:00:27.241562 IP6 (hlim 255, next-header: ICMPv6 (58), length: 32)
quince.home.blizinski.pl > ff02::1:ff00:1: [icmp6 sum ok] ICMP6,
neighbor solicitation, length 32, who has openwrt.home.blizinski.pl
source link-address option (1), length 8 (1): 00:1e:ec:8b:d0:be
Openwrt sends a reply packet:
21:00:27.242094 IP6 (hlim 255, next-header: ICMPv6 (58), length: 32)
openwrt.home.blizinski.pl > quince.home.blizinski.pl: [icmp6 sum ok] ICMP6,
neighbor advertisement, length 32, tgt is openwrt.home.blizinski.pl,
Flags [router, solicited, override]
destination link-address option (2), length 8 (1): 00:1e:e5:5b:13:83
And the packet is observed on eth0 (note that br0 != eth0) on quince:
21:00:25.601567 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32)
openwrt.home.blizinski.pl > quince.home.blizinski.pl: [icmp6 sum ok] ICMP6,
neighbor advertisement, length 32, tgt is openwrt.home.blizinski.pl,
Flags [router, solicited, override]
destination link-address option (2), length 8 (1): 00:1e:e5:5b:13:83
When tcpdump is done on br0 on quince, the netighbor solicitation packet is not
observed. On eth0 it is seen:
quince ~ # tcpdump -i eth0 ip6
tcpdump: WARNING: eth0: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
21:43:33.163586 IP6 quince.home.blizinski.pl > ff02::1:ff00:1: ICMP6, neighbor solicitation, who has openwrt.home.blizinski.pl, length 32
21:43:33.164345 IP6 openwrt.home.blizinski.pl > quince.home.blizinski.pl: ICMP6, neighbor advertisement, tgt is openwrt.home.blizinski.pl, length 32
21:43:34.159781 IP6 quince.home.blizinski.pl > ff02::1:ff00:1: ICMP6, neighbor solicitation, who has openwrt.home.blizinski.pl, length 32
21:43:34.160522 IP6 openwrt.home.blizinski.pl > quince.home.blizinski.pl: ICMP6, neighbor advertisement, tgt is openwrt.home.blizinski.pl, length 32
21:43:35.159587 IP6 quince.home.blizinski.pl > ff02::1:ff00:1: ICMP6, neighbor solicitation, who has openwrt.home.blizinski.pl, length 32
21:43:35.160103 IP6 openwrt.home.blizinski.pl > quince.home.blizinski.pl: ICMP6, neighbor advertisement, tgt is openwrt.home.blizinski.pl, length 32
On br0, it is not:
quince ~ # tcpdump -i br0 ip6
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on br0, link-type EN10MB (Ethernet), capture size 96 bytes
21:37:33.913233 IP6 openwrt.home.blizinski.pl > quince.home.blizinski.pl: ICMP6, neighbor advertisement, tgt is openwrt.home.blizinski.pl, length 32
21:37:34.913327 IP6 openwrt.home.blizinski.pl > quince.home.blizinski.pl: ICMP6, neighbor advertisement, tgt is openwrt.home.blizinski.pl, length 32
21:37:35.912198 IP6 openwrt.home.blizinski.pl > quince.home.blizinski.pl: ICMP6, neighbor advertisement, tgt is openwrt.home.blizinski.pl, length 32
The problem goes away when the surplus route is removed from eth0.
ip -6 route del 2001:770:18d::/64 dev eth0
My theory is that when the neighbor solicitation packet is being sent, it hits
the first eth0 rule and originates at eth0, and not br0. When a reply is sent,
it is aimed at eth0. The bridge software decides that this packet does not
belong to the bridge and doesn't send it there. The packet is probably dropped.
I can't come up with a more detailed idea. The bridge has the
same MAC address as eth0. What then is the difference between packets
originating from eth0 and originating from br0?
root@OpenWrt:~# tcpdump -v ip6
tcpdump: listening on br-lan, link-type EN10MB (Ethernet), capture size 96 bytes
22:03:56.365337 IP6 (hlim 255, next-header: ICMPv6 (58), length: 32)
quince.home.blizinski.pl > ff02::1:ff00:1: [icmp6 sum ok] ICMP6,
neighbor solicitation, length 32, who has openwrt.home.blizinski.pl
source link-address option (1), length 8 (1): 00:1e:ec:8b:d0:be
22:03:56.365837 IP6 (hlim 255, next-header: ICMPv6 (58), length: 32)
openwrt.home.blizinski.pl > quince.home.blizinski.pl: [icmp6 sum ok] ICMP6,
neighbor advertisement, length 32, tgt is openwrt.home.blizinski.pl,
Flags [router, solicited, override]
I can see no difference between the packet that generates a reply to eth0 and
the packet that generates a reply to br0. Perhaps the difference isn't caught in
this tcpdump output.
Does anyone have a better notion of what's happening between the bridge and
neighbor discovery protocol?
When specific parts are being looked at, they seem to do what they are supposed
to. Autoconfiguration adds IPv6 addresses and routes. The bridge software
attaches interfaces to briges. But the whole system is broken. Where is the
problem in your opinion?
IPv6 addess autoconfiguration vs bridged interface on Linux
Jeroen Massar on Friday, 30 January 2009 23:17:55
When you make a bridge over two interfaces, you should only use the bridge device, thus remove all addresses from the underlying devices. Also the bridge should have a different MAC address than any other interfaces, they are supposed to be globally unique.
IPv6 addess autoconfiguration vs bridged interface on Linux
Shadow Hawkins on Saturday, 31 January 2009 12:59:51
I did a bit of research on where does a bridge get its mac address from. As far as Linux is concerned, if I'm not mistaken, it happens exactly here:
http://www.isovarvas.com/lxr/http/source/net/bridge/br_fdb.c?a=alpha#L328
...and the line reads:
328 memcpy(fdb->addr.addr, addr, ETH_ALEN);
Which basically means: the MAC address is being copied from the interface being attached.
When a new bridge is being created, it has a MAC address.
At the first stage, the MAC address is set to 0 in this function (in line 156):
http://www.isovarvas.com/lxr/http/source/net/bridge/br_if.c?a=x86#L136
I didn't work out how and where the MAC address of a fresh bridge is set, but it is being set to some value:
10: br1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop
link/ether ce:8f:70:aa:57:c3 brd ff:ff:ff:ff:ff:ff
After eth0 is attached to the bridge, the bridge has the MAC address of eth0:
10: br1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop
link/ether 00:1e:ec:8b:d0:be brd ff:ff:ff:ff:ff:ff
I worked out a bit more of what's happening with the neighbor discovery. The neighbor solicitation packet originates at eth0, and the reply is being sent back with the MAC address of eth0, but because the MAC address of the bridge interface is identical, the packet is being routed to the bridge. In summary:
route present on eth0: (broken)
- neighbor solicitation seen on quince on eth0 but not on br0
- neighbor advertisement seen on quince on both eth0 and br0
route absent on eth0: (working)
- neighbor solicitation seen on quince on both eth0 and br0
- neighbor advertisement seen on quince on both eth0 and br0
If IPv6 autoconfiguration is done and route added, whos responsibility it is to remove the route and address when appropriate?
IPv6 addess autoconfiguration vs bridged interface on Linux
Jeroen Massar on Saturday, 31 January 2009 13:08:15
put in /etc/sysctl.conf:
net.ipv6.conf.eth0.accept_ra=0
and it should not appear there anymore.
IPv6 addess autoconfiguration vs bridged interface on Linux
Shadow Hawkins on Saturday, 31 January 2009 20:13:35
Thanks for the tip, this works!
Posting is only allowed when you are logged in. |