netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* netfilter: marking IPv6 packets sends them to the wrong interface
@ 2011-01-23 12:21 Mario 'BitKoenig' Holbe
  2011-01-24 13:46 ` Patrick McHardy
  0 siblings, 1 reply; 6+ messages in thread
From: Mario 'BitKoenig' Holbe @ 2011-01-23 12:21 UTC (permalink / raw)
  To: netfilter-devel; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 4472 bytes --]

Hello,

I have a strange issue with netfilter MARK on IPv6 which I cannot
explain and which I believe to be a kernel bug:
If I mark outgoing IPv6 packets they appear to be transmitted via the
wrong physical interface. At least multicast packets - at least some of
them.

I'm running a Linux-based router with two local interfaces and radvd
advertises stateless autoconfiguration information on them.
If I mark all outgoing IPv6 packets, after some time all hosts on both
subnets appear to be autoconfigured for both subnets, i.e. they all have
two IPv6 addresses - one of each subnet and two default routes - one for
each router interface. Of course, only one of them really works on each
host.

The gateway does pretty normal routing, no routing policies,
particularly no fwmark rules, does no bridging or something like that.
The network interfaces are Intel driven by e100.

The following debug session is done with a 2.6.32 kernel, the condensed
packet information originates from tcpdump:

Without marking everything runs as it should be.
Marking eth0 packets results in all advertisements transmitted via eth1.
The behaviour goes back to normal as soon as the marking disappears.
Marking eth1 packets doesn't appear to change the normal behaviour at
the first glance, but with that I experience hiccups after some time of
inactivity (i.e. from time to time ping6 from one subnet to the other
gets no answers for the first 6 to 8 packets). 

I also tried marking with 0xff00 instead of 1 - same results.
I tested this on kernels 2.6.26, 2.6.32, and 2.6.37 - all show the same
behaviour.

# ifconfig eth0; ifconfig eth1
eth0      Link encap:Ethernet  HWaddr 00:d0:b7:06:6b:36  
          inet addr:192.168.12.254  Bcast:192.168.12.255  Mask:255.255.255.0
          inet6 addr: 2001:6f8:90c:12::1/64 Scope:Global
          inet6 addr: fe80::2d0:b7ff:fe06:6b36/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
...
eth1      Link encap:Ethernet  HWaddr 00:a0:c9:e6:90:ce  
          inet addr:192.168.10.254  Bcast:192.168.10.255  Mask:255.255.255.0
          inet6 addr: 2001:6f8:90c:10::1/64 Scope:Global
          inet6 addr: fe80::2a0:c9ff:fee6:90ce/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
...
# ip -6 route show
2001:6f8:900:62f::/64 via :: dev sixxs  proto kernel  metric 256  mtu 1280 advmss 1220 hoplimit 0
2001:6f8:90c:10::/64 dev eth1  proto kernel  metric 256  mtu 1500 advmss 1432 hoplimit 0
2001:6f8:90c:12::/64 dev eth0  proto kernel  metric 256  mtu 1500 advmss 1432 hoplimit 0
fe80::/64 dev eth0  proto kernel  metric 256  mtu 1500 advmss 1432 hoplimit 0
fe80::/64 dev eth1  proto kernel  metric 256  mtu 1500 advmss 1432 hoplimit 0
fe80::/64 via :: dev sixxs  proto kernel  metric 256  mtu 1280 advmss 1220 hoplimit 0
default via 2001:6f8:900:62f::1 dev sixxs  metric 1024  mtu 1280 advmss 1220 hoplimit 0
# ip -6 rule list
0:      from all lookup local 
32766:  from all lookup main 
# zgrep BRI /proc/config.gz 
# CONFIG_BRIDGE is not set
# cat /etc/radvd.conf
interface eth0 {
        AdvSendAdvert on;
        prefix 2001:6f8:90c:12::/64 {};
};
interface eth1 {
        AdvSendAdvert on;
        prefix 2001:6f8:90c:10::/64 {};
};
# ip6tables -t raw -F
# ip6tables -t mangle -F
# ip6tables -t filter -F
# /etc/init.d/radvd start
-> eth0: fe80::2d0:b7ff:fe06:6b36 > ff02::1: prefix 2001:6f8:90c:12::/64
-> eth1: fe80::2a0:c9ff:fee6:90ce > ff02::1: prefix 2001:6f8:90c:10::/64
# /etc/init.d/radvd stop
# ip6tables -t mangle -A OUTPUT -o eth0 -j MARK --set-mark 1
# /etc/init.d/radvd start
-> eth0: <no traffic>
-> eth1: fe80::2a0:c9ff:fee6:90ce > ff02::1: prefix 2001:6f8:90c:10::/64
-> eth1: fe80::2d0:b7ff:fe06:6b36 > ff02::1: prefix 2001:6f8:90c:12::/64
# /etc/init.d/radvd stop
# ip6tables -t mangle -F
# /etc/init.d/radvd start
-> eth0: fe80::2d0:b7ff:fe06:6b36 > ff02::1: prefix 2001:6f8:90c:12::/64
-> eth1: fe80::2a0:c9ff:fee6:90ce > ff02::1: prefix 2001:6f8:90c:10::/64
# /etc/init.d/radvd stop
# ip6tables -t mangle -A OUTPUT -o eth1 -j MARK --set-mark 1
# /etc/init.d/radvd start
-> eth0: fe80::2d0:b7ff:fe06:6b36 > ff02::1: prefix 2001:6f8:90c:12::/64
-> eth1: fe80::2a0:c9ff:fee6:90ce > ff02::1: prefix 2001:6f8:90c:10::/64
# /etc/init.d/radvd stop

-- 
Doing it right is no excuse for not meeting the schedule.
                                -- Plant Manager, Delphi Corporation

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 482 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: netfilter: marking IPv6 packets sends them to the wrong interface
  2011-01-23 12:21 netfilter: marking IPv6 packets sends them to the wrong interface Mario 'BitKoenig' Holbe
@ 2011-01-24 13:46 ` Patrick McHardy
  2011-01-24 14:35   ` Mario 'BitKoenig' Holbe
  0 siblings, 1 reply; 6+ messages in thread
From: Patrick McHardy @ 2011-01-24 13:46 UTC (permalink / raw)
  To: Mario 'BitKoenig' Holbe, netfilter-devel, linux-kernel

On 23.01.2011 13:21, Mario 'BitKoenig' Holbe wrote:
> Hello,
> 
> I have a strange issue with netfilter MARK on IPv6 which I cannot
> explain and which I believe to be a kernel bug:
> If I mark outgoing IPv6 packets they appear to be transmitted via the
> wrong physical interface. At least multicast packets - at least some of
> them.
> 
> I'm running a Linux-based router with two local interfaces and radvd
> advertises stateless autoconfiguration information on them.
> If I mark all outgoing IPv6 packets, after some time all hosts on both
> subnets appear to be autoconfigured for both subnets, i.e. they all have
> two IPv6 addresses - one of each subnet and two default routes - one for
> each router interface. Of course, only one of them really works on each
> host.
> 
> The gateway does pretty normal routing, no routing policies,
> particularly no fwmark rules, does no bridging or something like that.
> The network interfaces are Intel driven by e100.
> 
> The following debug session is done with a 2.6.32 kernel, the condensed
> packet information originates from tcpdump:
> 
> Without marking everything runs as it should be.
> Marking eth0 packets results in all advertisements transmitted via eth1.
> The behaviour goes back to normal as soon as the marking disappears.
> Marking eth1 packets doesn't appear to change the normal behaviour at
> the first glance, but with that I experience hiccups after some time of
> inactivity (i.e. from time to time ping6 from one subnet to the other
> gets no answers for the first 6 to 8 packets). 
> 
> I also tried marking with 0xff00 instead of 1 - same results.
> I tested this on kernels 2.6.26, 2.6.32, and 2.6.37 - all show the same
> behaviour.

That probably means that we're not using the correct keys
when rerouting in ip6_route_me_harder(). Just for testing,
please try to disable the ip6_route_me_harder() call in
net/ipv6/netfilter/ip6table_mangle.c::ip6t_mangle_out().


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: netfilter: marking IPv6 packets sends them to the wrong interface
  2011-01-24 13:46 ` Patrick McHardy
@ 2011-01-24 14:35   ` Mario 'BitKoenig' Holbe
  2011-01-24 16:10     ` Patrick McHardy
  0 siblings, 1 reply; 6+ messages in thread
From: Mario 'BitKoenig' Holbe @ 2011-01-24 14:35 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netfilter-devel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 874 bytes --]

On Mon, Jan 24, 2011 at 02:46:57PM +0100, Patrick McHardy wrote:
> On 23.01.2011 13:21, Mario 'BitKoenig' Holbe wrote:
> > Without marking everything runs as it should be.
> > Marking eth0 packets results in all advertisements transmitted via eth1.
> > The behaviour goes back to normal as soon as the marking disappears.
> > I also tried marking with 0xff00 instead of 1 - same results.
> That probably means that we're not using the correct keys
> when rerouting in ip6_route_me_harder(). Just for testing,
> please try to disable the ip6_route_me_harder() call in
> net/ipv6/netfilter/ip6table_mangle.c::ip6t_mangle_out().

Yes, disabling the ip6_route_me_harder() call in ip6t_mangle_out()
results in the advertisements being transmitted on the correct
interfaces.


Mario
-- 
I thought the only thing the internet was good for was porn.  -- Futurama

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 482 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: netfilter: marking IPv6 packets sends them to the wrong interface
  2011-01-24 14:35   ` Mario 'BitKoenig' Holbe
@ 2011-01-24 16:10     ` Patrick McHardy
  2011-01-24 17:02       ` Mario 'BitKoenig' Holbe
  0 siblings, 1 reply; 6+ messages in thread
From: Patrick McHardy @ 2011-01-24 16:10 UTC (permalink / raw)
  To: Mario 'BitKoenig' Holbe, netfilter-devel, linux-kernel,
	NetDev

Am 24.01.2011 15:35, schrieb Mario 'BitKoenig' Holbe:
> On Mon, Jan 24, 2011 at 02:46:57PM +0100, Patrick McHardy wrote:
>> On 23.01.2011 13:21, Mario 'BitKoenig' Holbe wrote:
>>> Without marking everything runs as it should be.
>>> Marking eth0 packets results in all advertisements transmitted via eth1.
>>> The behaviour goes back to normal as soon as the marking disappears.
>>> I also tried marking with 0xff00 instead of 1 - same results.
>> That probably means that we're not using the correct keys
>> when rerouting in ip6_route_me_harder(). Just for testing,
>> please try to disable the ip6_route_me_harder() call in
>> net/ipv6/netfilter/ip6table_mangle.c::ip6t_mangle_out().
> 
> Yes, disabling the ip6_route_me_harder() call in ip6t_mangle_out()
> results in the advertisements being transmitted on the correct
> interfaces

Thanks. The problem appears to be that ip6_route_me_harder()
only uses the socket's oif for the route lookup when the
socket is bound to an interface, but radvd uses IPV6_PKTINFO
to specify the outgoing interface.

I guess netfilter shouldn't be overriding IPV6_PKTINFO, but
we unfortunately have neither an indication of this nor the
original route lookup keys available at the time the packet
is rerouted.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: netfilter: marking IPv6 packets sends them to the wrong interface
  2011-01-24 16:10     ` Patrick McHardy
@ 2011-01-24 17:02       ` Mario 'BitKoenig' Holbe
  2011-01-24 17:50         ` Patrick McHardy
  0 siblings, 1 reply; 6+ messages in thread
From: Mario 'BitKoenig' Holbe @ 2011-01-24 17:02 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netfilter-devel, linux-kernel, NetDev

[-- Attachment #1: Type: text/plain, Size: 1504 bytes --]

On Mon, Jan 24, 2011 at 05:10:50PM +0100, Patrick McHardy wrote:
> > Yes, disabling the ip6_route_me_harder() call in ip6t_mangle_out()
> > results in the advertisements being transmitted on the correct
> > interfaces
> Thanks. The problem appears to be that ip6_route_me_harder()
> only uses the socket's oif for the route lookup when the
> socket is bound to an interface, but radvd uses IPV6_PKTINFO
> to specify the outgoing interface.
> 
> I guess netfilter shouldn't be overriding IPV6_PKTINFO, but
> we unfortunately have neither an indication of this nor the
> original route lookup keys available at the time the packet
> is rerouted.

Mh, I'm not sure, but I guess an indication of netfilter not overriding
IPV6_PKTINFO could be the fact that the source address does not
change...

From my 1st mail:
| # ip6tables -t mangle -A OUTPUT -o eth0 -j MARK --set-mark 1
| # /etc/init.d/radvd start
| -> eth0: <no traffic>
| -> eth1: fe80::2a0:c9ff:fee6:90ce > ff02::1: prefix 2001:6f8:90c:10::/64
| -> eth1: fe80::2d0:b7ff:fe06:6b36 > ff02::1: prefix 2001:6f8:90c:12::/64

fe80::2d0:b7ff:fe06:6b36 is the link-local address of eth0 set by radvd
in IPV6_PKTINFO as well. This, of course, is no guarantee for
ipi6_ifindex not being changed, but I believe if something would have
changed it, it would also have changed ipi6_addr.


Mario
-- 
Doing it right is no excuse for not meeting the schedule.
                                -- Plant Manager, Delphi Corporation

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 482 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: netfilter: marking IPv6 packets sends them to the wrong interface
  2011-01-24 17:02       ` Mario 'BitKoenig' Holbe
@ 2011-01-24 17:50         ` Patrick McHardy
  0 siblings, 0 replies; 6+ messages in thread
From: Patrick McHardy @ 2011-01-24 17:50 UTC (permalink / raw)
  To: Mario 'BitKoenig' Holbe, netfilter-devel, linux-kernel,
	NetDev

Am 24.01.2011 18:02, schrieb Mario 'BitKoenig' Holbe:
> On Mon, Jan 24, 2011 at 05:10:50PM +0100, Patrick McHardy wrote:
>>> Yes, disabling the ip6_route_me_harder() call in ip6t_mangle_out()
>>> results in the advertisements being transmitted on the correct
>>> interfaces
>> Thanks. The problem appears to be that ip6_route_me_harder()
>> only uses the socket's oif for the route lookup when the
>> socket is bound to an interface, but radvd uses IPV6_PKTINFO
>> to specify the outgoing interface.
>>
>> I guess netfilter shouldn't be overriding IPV6_PKTINFO, but
>> we unfortunately have neither an indication of this nor the
>> original route lookup keys available at the time the packet
>> is rerouted.
> 
> Mh, I'm not sure, but I guess an indication of netfilter not overriding
> IPV6_PKTINFO could be the fact that the source address does not
> change...

No, ip6_route_me_harder() only attaches a new route to the packet,
the packets contents are not changed.

> From my 1st mail:
> | # ip6tables -t mangle -A OUTPUT -o eth0 -j MARK --set-mark 1
> | # /etc/init.d/radvd start
> | -> eth0: <no traffic>
> | -> eth1: fe80::2a0:c9ff:fee6:90ce > ff02::1: prefix 2001:6f8:90c:10::/64
> | -> eth1: fe80::2d0:b7ff:fe06:6b36 > ff02::1: prefix 2001:6f8:90c:12::/64
> 
> fe80::2d0:b7ff:fe06:6b36 is the link-local address of eth0 set by radvd
> in IPV6_PKTINFO as well. This, of course, is no guarantee for
> ipi6_ifindex not being changed, but I believe if something would have
> changed it, it would also have changed ipi6_addr.

No, what is happening is that radvd sends the packet with a specified
ifindex using IPV6_PKTINFO. The mangle table notices that the mark
changes and calls ip6_route_me_harder(), which performs a new route
lookup without taking the specified oif into account. It therefore
chooses the first of your two routes and sends the packet out eth1.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-01-24 17:50 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-01-23 12:21 netfilter: marking IPv6 packets sends them to the wrong interface Mario 'BitKoenig' Holbe
2011-01-24 13:46 ` Patrick McHardy
2011-01-24 14:35   ` Mario 'BitKoenig' Holbe
2011-01-24 16:10     ` Patrick McHardy
2011-01-24 17:02       ` Mario 'BitKoenig' Holbe
2011-01-24 17:50         ` Patrick McHardy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).