netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [Patch][IPv6] Fix wrong routing mechanism for Link Local IPv6 packets
@ 2017-05-16 15:37 Michael Ulmer
  2017-05-17 15:39 ` David Miller
  0 siblings, 1 reply; 11+ messages in thread
From: Michael Ulmer @ 2017-05-16 15:37 UTC (permalink / raw)
  To: netdev@vger.kernel.org

Blast from the past. 10 years back Wei Dong submitted the patch found (amongst several places) here:
http://lists.openwall.net/netdev/2007/01/30/20

Problem:
I have a firewall rule that DNATs ipv6 traffic from a destination address to ::1. The route lookup gives me the Main table & forwards that DNAT'd traffic instead of sending it to local process.

Example:
Looking at this from a netfilter point of view, a client (IP of fd00::5) requests a web page at [2000::25:0:0:1]:8080. The firewall rule DNATs it to ::1 (note that I threw a -j TRACE in raw's REROUTING).
TRACE: nat:PREROUTING:rule:2 SRC=fd00::5 DST=2000::25:0:0:1
TRACE: mangle:FORWARD:rule:1 SRC=fd00::5 DST=::1

The patch is verbatim (as is the subject line for this email). Traffic DNAT'd to ::1 now goes to mangle's INPUT chain after routing decision. I'm not sure why it was removed--I'm assuming it was an accident--as I can't find a record in the mailing list archive.

diff --git a/gpl/kernel/linux/net/ipv6/route.c b/gpl/kernel/linux/net/ipv6/route.c
index 3809ca2..2a2563f 100644
--- a/gpl/kernel/linux/net/ipv6/route.c
+++ b/gpl/kernel/linux/net/ipv6/route.c
@@ -611,7 +611,7 @@ static int rt6_score_route(struct rt6_info *rt, int oif,
        int m;
 
        m = rt6_check_dev(rt, oif);
-       if (!m && (strict & RT6_LOOKUP_F_IFACE))
+       if (!m && (rt->rt6i_flags & RTF_CACHE) && (strict & RT6_LOOKUP_F_IFACE))
                return RT6_NUD_FAIL_HARD;
 #ifdef CONFIG_IPV6_ROUTER_PREF
        m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2;



__
Mike Ulmer

^ permalink raw reply related	[flat|nested] 11+ messages in thread
[parent not found: <001101c744ec$5ee31720$ccb1220a@ZhaoleiSOTEC>]
* [Patch][IPv6] Fix wrong routing mechanism for Link Local IPv6 packets
@ 2007-01-30  7:12 weidong
  0 siblings, 0 replies; 11+ messages in thread
From: weidong @ 2007-01-30  7:12 UTC (permalink / raw)
  To: netdev; +Cc: usagi-users, yoshifuji

Hi, all
	When I tested linux-2.6.19.2, and found maybe there're some packet
routing bugs in linux kernel. My test topology is shown as the
following:

         eth0: fe80::20c:29ff:fe24:fa0a
            |                     eth1: fe80::20c:29ff:fe24:fa14 
            |                      |
------------------------------------------------
            |                      |
            |                      |
            | LAN1                 |LAN2
            |                      |
          -----
            ^
            |  
     Send Echo Request(src addr = fe80::200:ff:fe00:100)

Now we send Echo Request to eth1(ipv6 src addr is fe80::200:ff:fe00:100,
ipv6 dst addr is fe80::20c:29ff:fe24:fa14) on LAN1. Linux will send
ICMPv6 Redirect Packet to us. And the TargetAddress =
fe80::20c:29ff:fe24:fa14, DestinationAddress = fe80::20c:29ff:fe24:fa14.
Obviously, Linux considers that fe80::200:ff:fe00:100 and
fe80::20c:29ff:fe24:fa14 is on the SAME link(LAN0). In fact, kernel
invoke function ip6_foward().

When Linux decides whether or not making use of a rt6_info entry, it
will match the rt->rt6i_idev and rt->rt6_dev. This is done in function
rt6_check_dev(). If nothing matched, rt6_check_dev() return 0. Then
function rt6_score_route() will check whether the matched ipv6 addr
(fe80::20c:29ff:fe24:fa14 in our example) is a link local ipv6 address.
If it is a link local address, and "rt->rt6i_idev" "rt->rt6_dev" match
failed -- rt6_check_dev() return 0. Function rt6_score_route() return -1
directly. I think here is a problem. 

When kernel match eth1 addr with rt6_info entries, it will lookup in
local_table first. In rt6_check_dev() matching "rt->rt6i_idev" "rt-
>rt6_dev" will fail. The reason is oif = 2 , rt->rt6i_idev->dev->ifindex
is 3 and rt->rt6i_dev->ifindex is 1. I think even this match failed,
rt6_score_route() should not return -1, but return 0. And I think check
for RT6_LOOKUP_F_IFACE flag isn't needed here. Checking for this flag is
only needed in route cache when matching dst addr.

Due to the reason mentioned above, all entries in local table matching
dst addr fe80::20c:29ff:fe24:fa14 are failed. And then kernel matches
main table. fe80::/64 entry in main table will match successfully. Later
ip6_rt_copy() will copy the function pointer rt->u.dst.input. Obviously
rt->u.dst.input in main table is ip6_forward().

The following is my patch.

signed-off-by: Wei Dong <weid@np.css.fujitsu.com>

diff -ruN old/net/ipv6/route.c new/net/ipv6/route.c
--- old/net/ipv6/route.c	2007-01-10 14:10:37.000000000 -0500
+++ new/net/ipv6/route.c	2007-01-17 18:24:51.336774016 -0500
@@ -343,7 +343,7 @@
 	int m, n;
 		
 	m = rt6_check_dev(rt, oif);
-	if (!m && (strict & RT6_LOOKUP_F_IFACE))
+	if (!m && (rt->rt6i_flags & RTF_CACHE) && (strict & RT6_LOOKUP_F_IFACE))
 		return -1;
 #ifdef CONFIG_IPV6_ROUTER_PREF
 	m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2;




^ permalink raw reply	[flat|nested] 11+ messages in thread
* (usagi-users 03778) [Patch][IPv6] Fix wrong routing mechanism for Link Local IPv6 packets
@ 2007-01-30  7:02 weidong
  2007-01-30  7:24 ` YOSHIFUJI Hideaki / 吉藤英明
  0 siblings, 1 reply; 11+ messages in thread
From: weidong @ 2007-01-30  7:02 UTC (permalink / raw)
  To: netdev; +Cc: usagi-users, yoshifuji

Hi, all
	When I tested linux-2.6.19.2, and found maybe there're some packet
routing bugs in linux kernel. My test topology is shown as the
following:

         eth0: fe80::20c:29ff:fe24:fa0a
            |                     eth1: fe80::20c:29ff:fe24:fa14 
            |                      |
------------------------------------------------
            |                      |
            |                      |
            | LAN1                 |LAN2
            |                      |
          -----
            ^
            |  
     Send Echo Request(src addr = fe80::200:ff:fe00:100)

Now we send Echo Request to eth1(ipv6 src addr is fe80::200:ff:fe00:100,
ipv6 dst addr is fe80::20c:29ff:fe24:fa14) on LAN1. Linux will send
ICMPv6 Redirect Packet to us. And the TargetAddress =
fe80::20c:29ff:fe24:fa14, DestinationAddress = fe80::20c:29ff:fe24:fa14.
Obviously, Linux considers that fe80::200:ff:fe00:100 and
fe80::20c:29ff:fe24:fa14 is on the SAME link(LAN0). In fact, kernel
invoke function ip6_foward().

When Linux decides whether or not making use of a rt6_info entry, it
will match the rt->rt6i_idev and rt->rt6_dev. This is done in function
rt6_check_dev(). If nothing matched, rt6_check_dev() return 0. Then
function rt6_score_route() will check whether the matched ipv6 addr
(fe80::20c:29ff:fe24:fa14 in our example) is a link local ipv6 address.
If it is a link local address, and "rt->rt6i_idev" "rt->rt6_dev" match
failed -- rt6_check_dev() return 0. Function rt6_score_route() return -1
directly. I think here is a problem. 

When kernel match eth1 addr with rt6_info entries, it will lookup in
local_table first. In rt6_check_dev() matching "rt->rt6i_idev" "rt-
>rt6_dev" will fail. The reason is oif = 2 , rt->rt6i_idev->dev->ifindex
is 3 and rt->rt6i_dev->ifindex is 1. I think even this match failed,
rt6_score_route() should not return -1, but return 0. And I think check
for RT6_LOOKUP_F_IFACE flag isn't needed here. Checking for this flag is
only needed in route cache when matching dst addr.

Due to the reason mentioned above, all entries in local table matching
dst addr fe80::20c:29ff:fe24:fa14 are failed. And then kernel matches
main table. fe80::/64 entry in main table will match successfully. Later
ip6_rt_copy() will copy the function pointer rt->u.dst.input. Obviously
rt->u.dst.input in main table is ip6_forward().

The following is my patch.

signed-off-by: Wei Dong <weid@np.css.fujitsu.com>

diff -ruN old/net/ipv6/route.c new/net/ipv6/route.c
--- old/net/ipv6/route.c	2007-01-10 14:10:37.000000000 -0500
+++ new/net/ipv6/route.c	2007-01-17 18:24:51.336774016 -0500
@@ -343,7 +343,7 @@
 	int m, n;
 		
 	m = rt6_check_dev(rt, oif);
-	if (!m && (strict & RT6_LOOKUP_F_IFACE))
+	if (!m && (rt->rt6i_flags & RTF_CACHE) && (strict & RT6_LOOKUP_F_IFACE))
 		return -1;
 #ifdef CONFIG_IPV6_ROUTER_PREF
 	m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2;

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

end of thread, other threads:[~2017-05-17 15:39 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <001501c7444d$ed731020$ccb1220a@ZhaoleiSOTEC>
2007-01-30 23:47 ` [Patch][IPv6] Fix wrong routing mechanism for Link Local IPv6 packets weidong
     [not found] ` <1172069832.2682.18.camel@LINE>
2007-01-31  1:08   ` YOSHIFUJI Hideaki / 吉藤英明
2017-05-16 15:37 Michael Ulmer
2017-05-17 15:39 ` David Miller
     [not found] <001101c744ec$5ee31720$ccb1220a@ZhaoleiSOTEC>
2007-01-31  4:11 ` weidong
2007-01-31  5:09   ` YOSHIFUJI Hideaki / 吉藤英明
2007-01-31  5:14     ` (usagi-users 03788) " YOSHIFUJI Hideaki / 吉藤英明
2007-01-31  5:42       ` (usagi-users 03789) " YOSHIFUJI Hideaki / 吉藤英明
2007-02-05  0:59         ` David Miller
  -- strict thread matches above, loose matches on Subject: below --
2007-01-30  7:12 weidong
2007-01-30  7:02 (usagi-users 03778) " weidong
2007-01-30  7:24 ` YOSHIFUJI Hideaki / 吉藤英明
2007-01-30  7:55   ` Wei Dong
2007-01-30  8:40     ` YOSHIFUJI Hideaki / 吉藤英明

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).