Skip to contentSkip to conversation

IPv6 : add multicast routing verify which net_device is lo

PATCH In review Wang Xingtong 3 participants 6 messages Dec 20, 2011 – Dec 21, 2011

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 IPv6 : add multicast routing verify which net_device is lo

In currently routing subsystem, when we lookup a multicast routing to send muticast packets to outside, rt6_device_match will return the rt6_info which it's match first. if we add a multicast route on loopback devices beforce the others interface, rt6_device_match will retrun the rt6_info which rt6i_dev->name is "lo". But, obviously, we can't send a muticast packet to outside using loopback devices. It case all multicast packets blocking.

Commit 4af04aba93f47699e disabled kernel add multicast route on lo automatically. However, we can't surmise the routing-add order or interdict add multicast routing on loopback devices in user space. The bug still exist. So, i think more stronger routing subsystem is necessary.

---
 net/ipv6/route.c |   19 ++++++++++++++++---
 1 files changed, 16 insertions(+), 3 deletions(-)
net/ipv6/route.c +16 -3
index b582a0a..3871ef4 100644
@@ -334,9 +334,16 @@ static inline struct rt6_info *rt6_device_match(struct net *net,
     struct rt6_info *local = NULL;
     struct rt6_info *sprt;
 
-    if (!oif && ipv6_addr_any(saddr))
+    if (!oif && ipv6_addr_any(saddr)){
+        if (unlikely(rt->rt6i_dev->flags & IFF_LOOPBACK &&
+            ipv6_addr_is_multicast(&rt->rt6i_dst.addr))){
+            rt=rt->dst.rt6_next;
+            goto match;
+        }
         goto out;
+    }
 
+match:
     for (sprt = rt; sprt; sprt = sprt->dst.rt6_next) {
         struct net_device *dev = sprt->rt6i_dev;
 
@@ -355,9 +362,15 @@ static inline struct rt6_info *rt6_device_match(struct net *net,
                 local = sprt;
             }
         } else {
-            if (ipv6_chk_addr(net, saddr, dev,
-                      flags & RT6_LOOKUP_F_IFACE))
+            if (ipv6_addr_any(saddr)){
+                if (unlikely(rt->rt6i_dev->flags & IFF_LOOPBACK &&
+                    ipv6_addr_is_multicast(&rt->rt6i_dst.addr))){
+                    continue;
                 return sprt;
+            }
+            else if (ipv6_chk_addr(net, saddr, dev,
+                      flags & RT6_LOOKUP_F_IFACE))
+                    return sprt;
         }
     }
 
Signature · 1 line
1.7.1
#1 lore raw
Quoted 8 lines · Wang Xingtong

In currently routing subsystem, when we lookup a multicast routing to send muticast packets to outside, rt6_device_match will return the rt6_info which it's match first. if we add a multicast route on loopback devices beforce the others interface, rt6_device_match will retrun the rt6_info which rt6i_dev->name is "lo". But, obviously, we can't send a muticast packet to outside using loopback devices. It case all multicast packets blocking.

Quoted 5 lines

Commit 4af04aba93f47699e disabled kernel add multicast route on lo automatically. However, we can't surmise the routing-add order or interdict add multicast routing on loopback devices in user space. The bug still exist. So, i think more stronger routing subsystem is necessary.

sorry, the patch has some problem , i will send V2 later.

Quoted 49 lines
---
 net/ipv6/route.c |   19 ++++++++++++++++---
 1 files changed, 16 insertions(+), 3 deletions(-)
net/ipv6/route.c +16 -3
index b582a0a..3871ef4 100644
@@ -334,9 +334,16 @@ static inline struct rt6_info 
 *rt6_device_match(struct net *net,
     struct rt6_info *local = NULL;
     struct rt6_info *sprt;
 
-    if (!oif && ipv6_addr_any(saddr))
+    if (!oif && ipv6_addr_any(saddr)){
+        if (unlikely(rt->rt6i_dev->flags & IFF_LOOPBACK &&
+            ipv6_addr_is_multicast(&rt->rt6i_dst.addr))){
+            rt=rt->dst.rt6_next;
+            goto match;
+        }
         goto out;
+    }
 
+match:
     for (sprt = rt; sprt; sprt = sprt->dst.rt6_next) {
         struct net_device *dev = sprt->rt6i_dev;
@@ -355,9 +362,15 @@ static inline struct rt6_info 
 *rt6_device_match(struct net *net,
                 local = sprt;
             }
         } else {
-            if (ipv6_chk_addr(net, saddr, dev,
-                      flags & RT6_LOOKUP_F_IFACE))
+            if (ipv6_addr_any(saddr)){
+                if (unlikely(rt->rt6i_dev->flags & IFF_LOOPBACK &&
+                    ipv6_addr_is_multicast(&rt->rt6i_dst.addr))){
+                    continue;
                 return sprt;
+            }
+            else if (ipv6_chk_addr(net, saddr, dev,
+                      flags & RT6_LOOKUP_F_IFACE))
+                    return sprt;
         }
     }
#2 lore raw

PATCH v2 1/1 IPv6 : add multicast routing verify which net_device is lo

In currently routing subsystem, when we lookup a multicast routing to send muticast packets to outside, rt6_device_match will return the rt6_info which it's match first. If we add a multicast route on loopback devices beforce the others interface, rt6_device_match will retrun the rt6_info which rt6i_dev->name is "lo". But, obviously, we can't send a muticast packet to outside using loopback devices. It case all multicast packets blocking.

Commit 4af04aba93f47699e disabled kernel add multicast route on lo automatically. However, we can't surmise the routing-add order or interdict add multicast routing on loopback devices in user space. The bug still exist. So, i think, more stronger routing subsystem is necessary.

---
 net/ipv6/route.c |   19 ++++++++++++++++---
 1 files changed, 16 insertions(+), 3 deletions(-)
net/ipv6/route.c +16 -3
index b582a0a..d6663ca 100644
@@ -334,9 +334,16 @@ static inline struct rt6_info *rt6_device_match(struct net *net,
 	struct rt6_info *local = NULL;
 	struct rt6_info *sprt;
 
-	if (!oif && ipv6_addr_any(saddr))
+	if (!oif && ipv6_addr_any(saddr)){
+		if (unlikely(rt->rt6i_dev->flags & IFF_LOOPBACK &&
+			ipv6_addr_is_multicast(&rt->rt6i_dst.addr))){
+			rt=rt->dst.rt6_next;
+			goto match;
+		}
 		goto out;
+	}
 
+match:
 	for (sprt = rt; sprt; sprt = sprt->dst.rt6_next) {
 		struct net_device *dev = sprt->rt6i_dev;
 
@@ -355,9 +362,15 @@ static inline struct rt6_info *rt6_device_match(struct net *net,
 				local = sprt;
 			}
 		} else {
-			if (ipv6_chk_addr(net, saddr, dev,
-					  flags & RT6_LOOKUP_F_IFACE))
+			if (ipv6_addr_any(saddr)){
+				if (unlikely(rt->rt6i_dev->flags & IFF_LOOPBACK &&
+					ipv6_addr_is_multicast(&rt->rt6i_dst.addr)))
+					continue;
 				return sprt;
+			}
+			else if (ipv6_chk_addr(net, saddr, dev,
+					  flags & RT6_LOOKUP_F_IFACE))
+					return sprt;
 		}
 	}
 
Signature · 1 line
1.7.1
maintainer
#3 lore raw

From: Gao feng <[email protected]>
Date: Tue, 20 Dec 2011 19:10:24 +0800

Quoted 8 lines

In currently routing subsystem, when we lookup a multicast routing to send muticast packets to outside, rt6_device_match will return the rt6_info which it's match first. If we add a multicast route on loopback devices beforce the others interface, rt6_device_match will retrun the rt6_info which rt6i_dev->name is "lo". But, obviously, we can't send a muticast packet to outside using loopback devices. It case all multicast packets blocking.

Quoted 7 lines

Commit 4af04aba93f47699e disabled kernel add multicast route on lo automatically. However, we can't surmise the routing-add order or interdict add multicast routing on loopback devices in user space. The bug still exist. So, i think, more stronger routing subsystem is necessary.

Ok, this is getting rediculious. I want to revert all of this stuff.

How about, instead, we stop userland adding explicit addresses to the loopback device since that's what started behaving differently recently and causes these problems in the first place?

#4 lore raw
Quoted 18 lines

From: Gao feng <[email protected]>
Date: Tue, 20 Dec 2011 19:10:24 +0800

Quoted 14 lines

In currently routing subsystem, when we lookup a multicast routing to send muticast packets to outside, rt6_device_match will return the rt6_info which it's match first. If we add a multicast route on loopback devices beforce the others interface, rt6_device_match will retrun the rt6_info which rt6i_dev->name is "lo". But, obviously, we can't send a muticast packet to outside using loopback devices. It case all multicast packets blocking.

Commit 4af04aba93f47699e disabled kernel add multicast route on lo automatically. However, we can't surmise the routing-add order or interdict add multicast routing on loopback devices in user space. The bug still exist. So, i think, more stronger routing subsystem is necessary.

Quoted 8 lines
Quoted 1 line

Ok, this is getting rediculious. I want to revert all of this stuff.

How about, instead, we stop userland adding explicit addresses to the loopback device since that's what started behaving differently recently and causes these problems in the first place?

OK, David, I reproduce this as following :

1) ip -6 route show | grep ff00
unreachable ff00::/8 dev lo metric 1024 error -101 ff00::/8 dev eth1 metric 1024

2) ip -6 route del ff00::/8 dev eth1
ip -6 route del ff00::/8 dev lo

3) ip -6 route add ff00::/8 dev lo
ip -6 route add ff00::/8 dev eth1

now, if we join to the multicast group with the interface index is specified as 0, not restrict devices( oif == 0 ), not restrict saddr ( saddr == :: ), rt6_device_match will return rt6_info which rt6i_dev->name is "lo" all the while, and rt6i_dev->error is "-ENETUNREACH". we got "ENODEV" at userspace, all multicast packets will be blocked .

But, in fact, eth1 can be uesd and we missed. This is a bug in routing system, isn't it?

This patch add multicast routing check-up in rt6_device_match to arrest it return loopback device when we isn't specified interface and saddr.

thanks,

wang xingtong

maintainer
#5 lore raw

From: Wang Xingtong <[email protected]>
Date: Wed, 21 Dec 2011 17:01:21 +0800

Quoted 11 lines

OK, David, I reproduce this as following :

1) ip -6 route show | grep ff00
unreachable ff00::/8 dev lo metric 1024 error -101 ff00::/8 dev eth1 metric 1024

2) ip -6 route del ff00::/8 dev eth1
ip -6 route del ff00::/8 dev lo

3) ip -6 route add ff00::/8 dev lo
ip -6 route add ff00::/8 dev eth1

My answer is "Don't ever do that." The kernel sets up the loopback device with all the necessary parameters you need including the address, network prefix, and (once we revert the recent bogus ipv6 autoconf patch) the multicast prefix.

There is no reason to ever explicit set the things that the kernel takes care of for you.

That was exactly my point, the piece of userspace that has started doing this needs to be fixed and we need to revert Li Wei's recent patch.