Re: [Patch][IPv6] Fix wrong routing mechanism for Link Local IPv6 packets

2017-05-17 Thread David Miller
From: Michael Ulmer 
Date: Tue, 16 May 2017 15:37:39 +

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

It's not by accident, he received feedback from Yoshifuji and suggested
alternative ways to fix his problem:

http://marc.info/?l=linux-netdev=117020569620697=2

In fact, Yoshifuji stated that some of the behaviors are indeed
intentional.


[Patch][IPv6] Fix wrong routing mechanism for Link Local IPv6 packets

2017-05-16 Thread Michael Ulmer
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

Re: [Patch][IPv6] Fix wrong routing mechanism for Link Local IPv6 packets

2007-02-04 Thread David Miller
From: YOSHIFUJI Hideaki [EMAIL PROTECTED]
Date: Wed, 31 Jan 2007 14:42:50 +0900 (JST)

 [IPV6] ROUTE: Do not route packets to link-local address on other device.
 
 With help from Wei Dong [EMAIL PROTECTED].
 
 Signed-off-by: YOSHIFUJI Hideaki [EMAIL PROTECTED]

Applied, thank you.
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Patch][IPv6] Fix wrong routing mechanism for Link Local IPv6 packets

2007-01-30 Thread YOSHIFUJI Hideaki / 吉藤英明
In article [EMAIL PROTECTED] (at Tue, 30 Jan 2007 16:55:12 +0900), Wei Dong 
[EMAIL PROTECTED] says:

 Hello, Mr yoshfuji
 Take ping6 for example. Asumming there is a router which has 2 NICs. 
 eth0 on router has ipv6 addr fe80::20c:29ff:fe24:fa0a, eth1 on router has 
 ipv6 addr fe80::20c:29ff:fe24:fa14. Also there is a host connected to 
 router's eth0, and the host's ipv6 addr is fe80::200:ff:fe00:100. We ping6 
:

I still need more precise figure.

Please draw complete box for the 2-3 boxes (pinger, router (and the
destination)), link(s) and interfaces.

+-+
|Router   |
+---+-+---+
eth0| |eth1
| |
eth0|
+---+-+
|Host1|
+-+

Host1  eth0: fe80:
Router eth0: fe80:
Router eth1: fe80:...

Or, something like that

I think you may use other tool such as tgif etc.

--yoshfuji
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Patch][IPv6] Fix wrong routing mechanism for Link Local IPv6 packets

2007-01-30 Thread weidong
Hello, Mr yoshfuji:
Thanks for your reply.
The following is the figure.
||
|| 
| Router | 
|||---|
|   |--|   |--|  || other |
|   | eth0 |---| eth1 |--||network|
|   |--|  ||--|  ||---|
|--|--||-|
   |  v| 
   | fe80::20c:29ff:fe24:fa0a  | 
   |   | 
   |   | 
   |   | 
   |   | 
   |   | 
   |   v 
   |   fe80::20c:29ff:fe24:fa14 
   |   
   | 
|--|--| 
|  |--|   | 
|  | eth0 |---|---fe80::200:ff:fe00:100 
|  |--|   | 
| | 
|Host | 
|-| 

Host eth0: fe80::200:ff:fe00:100
Router eth0: fe80::20c:29ff:fe24:fa0a
Router eth1: fe80::20c:29ff:fe24:fa14

We ping6 from host's eth0 to Router's eth1. Echo Request's src addr =
fe80::200:ff:fe00:100, dst addr = fe80::20c:29ff:fe24:fa14. And Kernel
just send ICMPv6 redirect packet and then forward the Echo Request to
router's eth0. If we run tcpdump on Host eth0, we can receive the ICMPv6
Redirect packet. And if we send NA which advertises
fe80::20c:29ff:fe24:fa14 MAC address(this is very easy for v6eval tool),
we also can receive the forwarded Echo Request(src:fe80::200:ff:fe00:100
dst is fe80::20c:29ff:fe24:fa14). 

I dived into the kernel, and found that maybe function rt6_score_route()
has problems. In rt6_score_route(), if rt6_check_dev() return 0, and the
dst ipv6 addr is link local addr, rt6_socre_route() return -1 directly.
I think this is not correct, we should return -1 only if the entry is in
the route cache, and the dst addr is link local addr. Only entries in
cache may select wrong IPv6 Link Local NIC for a link local dst addr.
because they are copied from static IPv6 fib table entries.

  Hello, Mr yoshfuji
  Take ping6 for example. Asumming there is a router which has 2 NICs.
  eth0 on router has ipv6 addr fe80::20c:29ff:fe24:fa0a, eth1 on router has
  ipv6 addr fe80::20c:29ff:fe24:fa14. Also there is a host connected to
  router's eth0, and the host's ipv6 addr is fe80::200:ff:fe00:100. We ping6
 :
 
 I still need more precise figure.
 
 Please draw complete box for the 2-3 boxes (pinger, router (and the
 destination)), link(s) and interfaces.
 
 +-+
 |Router   |
 +---+-+---+
 eth0| |eth1
 | |
 eth0|
 +---+-+
 |Host1|
 +-+
 
 Host1  eth0: fe80:
 Router eth0: fe80:
 Router eth1: fe80:...
 
 Or, something like that
 
 I think you may use other tool such as tgif etc.
 
 --yoshfuji 
 

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Patch][IPv6] Fix wrong routing mechanism for Link Local IPv6 packets

2007-01-30 Thread YOSHIFUJI Hideaki / 吉藤英明
In article [EMAIL PROTECTED] (at Wed, 21 Feb 2007 09:57:12 -0500), weidong 
[EMAIL PROTECTED] says:

 The following is the figure.
:
 Host eth0: fe80::200:ff:fe00:100
 Router eth0: fe80::20c:29ff:fe24:fa0a
 Router eth1: fe80::20c:29ff:fe24:fa14

 Other network
  |
  | eth1
 +++
 | Router  |
 +++
  | eth0
  |
  | eth0
 +++
 |  Host   |
 +-+

 We ping6 from host's eth0 to Router's eth1. Echo Request's src addr =
 fe80::200:ff:fe00:100, dst addr = fe80::20c:29ff:fe24:fa14. And Kernel
 just send ICMPv6 redirect packet and then forward the Echo Request to
 router's eth0. If we run tcpdump on Host eth0, we can receive the ICMPv6
 Redirect packet. And if we send NA which advertises

This is correct, and intended behavior.

 fe80::20c:29ff:fe24:fa14 MAC address(this is very easy for v6eval tool),
 we also can receive the forwarded Echo Request(src:fe80::200:ff:fe00:100
 dst is fe80::20c:29ff:fe24:fa14). 

Well, this is known issue, actually.

While this cannot happen in normal operation, we should NOT accept
such traffic. :-)

Here is the (untested) fix.

-
[IPV6] ROUTE: Do not accept traffic for link-local address on different 
interface.

Signed-off-by: YOSHIFUJI Hideaki [EMAIL PROTECTED]

--- 
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 5f0043c..a7468e0 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -311,12 +311,19 @@ static inline void rt6_probe(struct rt6_info *rt)
 static int inline rt6_check_dev(struct rt6_info *rt, int oif)
 {
struct net_device *dev = rt-rt6i_dev;
+   int ret = 0;
+
+   if (dev-flags  IFF_LOOPBACK) {
+   if (!WARN_ON(rt-rt6i_idev == NULL) 
+   rt-rt6i_idev-dev-ifindex == oif)
+   ret = 1;
+   else
+   return 0;
+   }
if (!oif || dev-ifindex == oif)
return 2;
-   if ((dev-flags  IFF_LOOPBACK) 
-   rt-rt6i_idev  rt-rt6i_idev-dev-ifindex == oif)
-   return 1;
-   return 0;
+
+   return ret;
 }
 
 static int inline rt6_check_neigh(struct rt6_info *rt)

-- 
YOSHIFUJI Hideaki @ USAGI Project  [EMAIL PROTECTED]
GPG-FP  : 9022 65EB 1ECF 3AD1 0BDF  80D8 4807 F894 E062 0EEA
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Patch][IPv6] Fix wrong routing mechanism for Link Local IPv6 packets

2007-01-30 Thread weidong
Hello, Mr yoshfuji
Thanks for your patch. I think maybe we checking oif first is better,
and WARN_ON in function rt6_score_route().
The following is my patch

Signed-off-by: Wei Dong [EMAIL PROTECTED]

diff -ruN old/net/ipv6/route.c new/net/ipv6/route.c
--- old/net/ipv6/route.c2007-02-16 13:46:33.0 -0500
+++ new/net/ipv6/route.c2007-02-16 13:44:27.0 -0500
@@ -309,12 +309,21 @@
 static int inline rt6_check_dev(struct rt6_info *rt, int oif)
 {
struct net_device *dev = rt-rt6i_dev;
-   if (!oif || dev-ifindex == oif)
+   int ret = 0;
+
+   if (!oif)
return 2;
+
if ((dev-flags  IFF_LOOPBACK) 
rt-rt6i_idev  rt-rt6i_idev-dev-ifindex == oif)
-   return 1;
-   return 0;
+   ret = 1;
+   else
+   return 0;
+
+   if (dev-ifindex == oif)
+   return 2;
+
+   return ret;
 }
 
 static int inline rt6_check_neigh(struct rt6_info *rt)
@@ -339,8 +348,11 @@
int m, n;

m = rt6_check_dev(rt, oif);
-   if (!m  (strict  RT6_LOOKUP_F_IFACE))
+   if (!m  (strict  RT6_LOOKUP_F_IFACE)) {
+   WARN_ON(rt-rt6i_dev-flags  IFF_LOOPBACK);
return -1;
+   }
+
 #ifdef CONFIG_IPV6_ROUTER_PREF
m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt-rt6i_flags))  2;
 #endif


On Wed, 2007-01-31 at 13:00 +0900, Wei Dong wrote:
 In article [EMAIL PROTECTED] (at Wed, 21 Feb 2007 
 09:57:12 -0500), weidong [EMAIL PROTECTED] says:
 
  The following is the figure.
 :
  Host eth0: fe80::200:ff:fe00:100
  Router eth0: fe80::20c:29ff:fe24:fa0a
  Router eth1: fe80::20c:29ff:fe24:fa14
 
  Other network
   |
   | eth1
  +++
  | Router  |
  +++
   | eth0
   |
   | eth0
  +++
  |  Host   |
  +-+
 
  We ping6 from host's eth0 to Router's eth1. Echo Request's src addr =
  fe80::200:ff:fe00:100, dst addr = fe80::20c:29ff:fe24:fa14. And Kernel
  just send ICMPv6 redirect packet and then forward the Echo Request to
  router's eth0. If we run tcpdump on Host eth0, we can receive the ICMPv6
  Redirect packet. And if we send NA which advertises
 
 This is correct, and intended behavior.
 
  fe80::20c:29ff:fe24:fa14 MAC address(this is very easy for v6eval tool),
  we also can receive the forwarded Echo Request(src:fe80::200:ff:fe00:100
  dst is fe80::20c:29ff:fe24:fa14).
 
 Well, this is known issue, actually.
 
 While this cannot happen in normal operation, we should NOT accept
 such traffic. :-)
 
 Here is the (untested) fix.
 
 -
 [IPV6] ROUTE: Do not accept traffic for link-local address on different 
 interface.
 
 Signed-off-by: YOSHIFUJI Hideaki [EMAIL PROTECTED]
 
 --- 
 diff --git a/net/ipv6/route.c b/net/ipv6/route.c
 index 5f0043c..a7468e0 100644
 --- a/net/ipv6/route.c
 +++ b/net/ipv6/route.c
 @@ -311,12 +311,19 @@ static inline void rt6_probe(struct rt6_info *rt)
  static int inline rt6_check_dev(struct rt6_info *rt, int oif)
  {
   struct net_device *dev = rt-rt6i_dev;
 + int ret = 0;
 +
 + if (dev-flags  IFF_LOOPBACK) {
 + if (!WARN_ON(rt-rt6i_idev == NULL) 
 + rt-rt6i_idev-dev-ifindex == oif)
 + ret = 1;
 + else
 + return 0;
 + }
   if (!oif || dev-ifindex == oif)
   return 2;
 - if ((dev-flags  IFF_LOOPBACK) 
 - rt-rt6i_idev  rt-rt6i_idev-dev-ifindex == oif)
 - return 1;
 - return 0;
 +
 + return ret;
  }
 
  static int inline rt6_check_neigh(struct rt6_info *rt)
 

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Patch][IPv6] Fix wrong routing mechanism for Link Local IPv6 packets

2007-01-30 Thread YOSHIFUJI Hideaki / 吉藤英明
In article [EMAIL PROTECTED] (at Wed, 21 Feb 2007 23:51:45 -0500), weidong 
[EMAIL PROTECTED] says:

   Thanks for your patch. I think maybe we checking oif first is better,
 and WARN_ON in function rt6_score_route().

Please remove WARN_ON.  Otherwise, I'm fine with it.

--yoshfuji
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Patch][IPv6] Fix wrong routing mechanism for Link Local IPv6 packets

2007-01-29 Thread weidong
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 [EMAIL PROTECTED]

diff -ruN old/net/ipv6/route.c new/net/ipv6/route.c
--- old/net/ipv6/route.c2007-01-10 14:10:37.0 -0500
+++ new/net/ipv6/route.c2007-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;



-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Patch][IPv6] Fix wrong routing mechanism for Link Local IPv6 packets

2007-01-29 Thread YOSHIFUJI Hideaki / 吉藤英明
Hello.

In article [EMAIL PROTECTED] (at Wed, 21 Feb 2007 02:24:26 -0500), weidong 
[EMAIL PROTECTED] says:

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

Sorry, I could not understand this figure
Would you elaborate this?

--yoshfuji
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Patch][IPv6] Fix wrong routing mechanism for Link Local IPv6 packets

2007-01-29 Thread Wei Dong

Hello, Mr yoshfuji
   Take ping6 for example. Asumming there is a router which has 2 NICs. 
eth0 on router has ipv6 addr fe80::20c:29ff:fe24:fa0a, eth1 on router has 
ipv6 addr fe80::20c:29ff:fe24:fa14. Also there is a host connected to 
router's eth0, and the host's ipv6 addr is fe80::200:ff:fe00:100. We ping6 
to router's eth1(ipv6 addr fe80::20c:29ff:fe24:fa14). But now Linux kernel 
deals with this kind of packet incorrectly. Router forward the Echo request 
to eth0. And send ICMP redirect packet to the host. In ICMP redirect packt 
TargetAddress =fe80::20c:29ff:fe24:fa14, DestinationAddress = 
fe80::20c:29ff:fe24:fa14. So I think Linux  kernel considers that 
fe80::200:ff:fe00:100 and fe80::20c:29ff:fe24:fa14 are neighbors.


I dived into the kernel, and found that maybe function rt6_score_route() has 
problems. In rt6_score_route(), if rt6_check_dev() return 0, and the dst 
ipv6 addr is link local addr, rt6_socre_route() return -1 directly. I think 
this is not correct, we should return -1 only if the entry is in the route 
cache, and the dst addr is link local addr. Only entries in cache will 
select wrong IPv6 Link Local NIC for a link local addr, because they are 
copied from static IPv6 fib tables.


- Original Message - 

Hello.

In article [EMAIL PROTECTED] (at Wed, 21 Feb 2007 
02:24:26 -0500), weidong [EMAIL PROTECTED] says:



 eth0: fe80::20c:29ff:fe24:fa0a
| eth1: fe80::20c:29ff:fe24:fa14
|  |

|  |
|  |
| LAN1 |LAN2
|  |
  -
^
|
 Send Echo Request(src addr = fe80::200:ff:fe00:100)


Sorry, I could not understand this figure
Would you elaborate this?

--yoshfuji 


-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html