Skip to contentSkip to conversation

2.6.34 + IPv6: Oops?

PATCH Applied Andreas Klauer 5 participants 11 messages Jun 19, 2010 – Jun 26, 2010

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

Hi,

I have a NULL pointer dereference Oops here which I can reproduce, and I believe it's related to network / IPv6 somehow since sending a ping from outside to the IPv6 address is what ultimately triggers it.

The box is a dedicated server with a /64 subnet assigned to it. What I'm trying to do is tunnel part of it through IPv4 / OpenVPN. I'm completely new to IPv6 so I'm probably doing this horribly wrong.

Unfortunately I only have a screenshot of the Oops. I uploaded it along with other information here:

http://www.metamorpher.de/kernel/

Before the Oops I'm running a shell script (see link above) which among other things sets up proxy_ndp on eth0 (r8169 driver). The Oops is triggered by sending a ping from the outside world to the IP which was intended to be tunneled (2a01:4f8:120:8221:ffff::2).

If you need more information, I'll try my best to provide it. If it's a kernel bug, I'll also be happy to test any patches.

Regards
Andreas Klauer

#1 lore raw

Hi,

no one replied so far - am I reporting this to the wrong place? Please advise.

I've done some more testing; I can reproduce the issue now on different hardware (my desktop at home), with a clean environment (freshly boot- strapped Debian Lenny). Which should make things more interesting.

The issue seems to be compiler related. It occurs if the kernel is compiled with Debian Lenny "gcc (Debian 4.3.2-1.1) 4.3.2". It does not occur (or at least I can't reproduce it) if the kernel was compiled with Gentoo "gcc (Gentoo 4.4.4 p1.0) 4.4.4".

Screenshot:
http://www.metamorpher.de/kernel/panic2.jpg

Steps to reproduce:
http://www.metamorpher.de/kernel/steps-to-reproduce.txt

kernel config and lspci also available here:
http://www.metamorpher.de/kernel/

Regards
Andreas Klauer

#2 lore raw
Quoted 23 lines · On Mon, 21 Jun 2010 17:30:18 +0200 Andreas Klauer…

Hi,

no one replied so far - am I reporting this to the wrong place? Please advise.

I've done some more testing; I can reproduce the issue now on different hardware (my desktop at home), with a clean environment (freshly boot- strapped Debian Lenny). Which should make things more interesting.

The issue seems to be compiler related. It occurs if the kernel is compiled with Debian Lenny "gcc (Debian 4.3.2-1.1) 4.3.2". It does not occur (or at least I can't reproduce it) if the kernel was compiled with Gentoo "gcc (Gentoo 4.4.4 p1.0) 4.4.4".

Screenshot:
http://www.metamorpher.de/kernel/panic2.jpg

Steps to reproduce:
http://www.metamorpher.de/kernel/steps-to-reproduce.txt

kernel config and lspci also available here:
http://www.metamorpher.de/kernel/

Quoted 6 lines

Regards
Andreas Klauer
--
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

Unfortunately, Greg seems to be slow in getting 2.6.34.1 out. These patches are related:

http://marc.info/?l=linux-netdev&m=127472600330413
http://marc.info/?l=linux-netdev&m=127472599530407

#4 lore raw
In reply to Andreas Klauer
Quoted 4 lines · * Andreas Klauer | 2010-06-21 17:30:18 [+0200]:

Hi,

no one replied so far - am I reporting this to the wrong place? Please advise.

It is the right place, some guys are in holiday but probably you can git bisect the problem?

HGN

#5 lore raw

The OOPS is here
static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
const struct in6_addr *daddr,
const struct in6_addr *solicited_addr, int router, int solicited, int override, int inc_opt)
{
...

	/* for anycast or proxy, solicited_addr != src_addr */
	ifp = ipv6_get_ifaddr(dev_net(dev), solicited_addr, dev, 1);
	if (ifp) {
		src_addr = solicited_addr;
		if (ifp->flags & IFA_F_OPTIMISTIC)
			override = 0;
		in6_ifa_put(ifp);
	} else {
		if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
				       inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs,
				       &tmpaddr))
			return;
		src_addr = &tmpaddr;
	}

	icmp6h.icmp6_router = router;
	icmp6h.icmp6_solicited = solicited;
	icmp6h.icmp6_override = override;

	inc_opt |= ifp->idev->cnf.force_tllao;

And it caused by this recent commit.

Author: Octavian Purdila <[email protected]> 2009-10-02 04:39:15
Committer: David S. Miller <[email protected]> 2009-10-07 01:10:45
Parent: d1f8297a96b0d70f17704296a6666468f2087ce6 (Revert "sit: stateless autoconf for isatap")
Child: d7fc02c7bae7b1cf69269992cf880a43a350cdaa (Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6)
Branches: addrconf, master, remotes/origin/master
Follows: v2.6.32-rc3
Precedes: v2.6.33-rc1

make TLLAO option for NA packets configurable

On Friday 02 October 2009 20:53:51 you wrote:

> This is good although I would have shortened the name.

Ah, I knew I forgot something :) Here is v4.

tavi

>From 24d96d825b9fa832b22878cc6c990d5711968734 Mon Sep 17 00:00:00 2001
From: Octavian Purdila <[email protected]>
Date: Fri, 2 Oct 2009 00:51:15 +0300
Subject: [PATCH] ipv6: new sysctl for sending TLLAO with unicast NAs

Neighbor advertisements responding to unicast neighbor solicitations did not include the target link-layer address option. This patch adds a new sysctl option (disabled by default) which controls whether this option should be sent even with unicast NAs.

The need for this arose because certain routers expect the TLLAO in some situations even as a response to unicast NS packets.

Moreover, RFC 2461 recommends sending this to avoid a race condition (section 4.4, Target link-layer address)

It is not handling the case of ifp == NULL.

Maybe the following (move the assignment into the if block).

net/ipv6/ndisc.c +1 -1
@@ -586,6 +586,7 @@ static void ndisc_send_na(struct net_dev
 		src_addr = solicited_addr;
 		if (ifp->flags & IFA_F_OPTIMISTIC)
 			override = 0;
+		inc_opt |= ifp->idev->cnf.force_tllao;
 		in6_ifa_put(ifp);
 	} else {
 		if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
@@ -599,7 +600,6 @@ static void ndisc_send_na(struct net_dev
 	icmp6h.icmp6_solicited = solicited;
 	icmp6h.icmp6_override = override;
 
-	inc_opt |= ifp->idev->cnf.force_tllao;
 	__ndisc_send(dev, neigh, daddr, src_addr,
 		     &icmp6h, solicited_addr,
 		     inc_opt ? ND_OPT_TARGET_LL_ADDR : 0);
#6 lore raw
Quoted 18 lines · Stephen Hemminger

It is not handling the case of ifp == NULL.

Maybe the following (move the assignment into the if block).

net/ipv6/ndisc.c +1 -0
@@ -586,6 +586,7 @@ static void ndisc_send_na(struct net_dev
 		src_addr = solicited_addr;
 		if (ifp->flags & IFA_F_OPTIMISTIC)
 			override = 0;
+		inc_opt |= ifp->idev->cnf.force_tllao;
 		in6_ifa_put(ifp);
 	} else {
 		if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,

net/ipv6/ndisc.c static void ndisc_send_na(struct net_dev · line 605

Quoted 7 lines
net/ipv6/ndisc.c +0 -1
@@ -599,7 +600,6 @@ static void ndisc_send_na(struct net_dev
 	icmp6h.icmp6_solicited = solicited;
 	icmp6h.icmp6_override = override;
 
-	inc_opt |= ifp->idev->cnf.force_tllao;
 	__ndisc_send(dev, neigh, daddr, src_addr,
 		     &icmp6h, solicited_addr,
 		     inc_opt ? ND_OPT_TARGET_LL_ADDR : 0);

Thanks a lot! This fix seems to work fine for me (tested locally only). I'll see what happens when I apply it to my server tomorrow.

Curious though as to why I wasn't able to reproduce it when compiling the kernel with Gentoo's GCC. It doesn't look like it should make any difference. Maybe I made a mistake when I tested it with Gentoo.

Regards
Andreas Klauer

#7 lore raw

PATCH 1/1 ipv6: fix NULL reference in proxy neighbor discovery

The addition of TLLAO option created a kernel OOPS regression for the case where neighbor advertisement is being sent via proxy path. When using proxy, ipv6_get_ifaddr() returns NULL causing the NULL dereference.

Change causing the bug was:
commit f7734fdf61ec6bb848e0bafc1fb8bad2c124bb50

Author: Octavian Purdila <[email protected]>
Date:   Fri Oct 2 11:39:15 2009 +0000

make TLLAO option for NA packets configurable

---
Patch for -net and -stable.
Applies to 2.6.33 and later.

net/ipv6/ndisc.c +1 -1
@@ -586,6 +586,7 @@ static void ndisc_send_na(struct net_dev
 		src_addr = solicited_addr;
 		if (ifp->flags & IFA_F_OPTIMISTIC)
 			override = 0;
+		inc_opt |= ifp->idev->cnf.force_tllao;
 		in6_ifa_put(ifp);
 	} else {
 		if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
@@ -599,7 +600,6 @@ static void ndisc_send_na(struct net_dev
 	icmp6h.icmp6_solicited = solicited;
 	icmp6h.icmp6_override = override;
 
-	inc_opt |= ifp->idev->cnf.force_tllao;
 	__ndisc_send(dev, neigh, daddr, src_addr,
 		     &icmp6h, solicited_addr,
 		     inc_opt ? ND_OPT_TARGET_LL_ADDR : 0);
Acked-by on v1 1/1
#8 lore raw

Re: [PATCH] ipv6: fix NULL reference in proxy neighbor discovery

Quoted 40 lines · Stephen Hemminger

The addition of TLLAO option created a kernel OOPS regression for the case where neighbor advertisement is being sent via proxy path. When using proxy, ipv6_get_ifaddr() returns NULL causing the NULL dereference.

Change causing the bug was:
commit f7734fdf61ec6bb848e0bafc1fb8bad2c124bb50

Author: Octavian Purdila<[email protected]>
Date:   Fri Oct 2 11:39:15 2009 +0000

make TLLAO option for NA packets configurable

---
Patch for -net and -stable.
Applies to 2.6.33 and later.

net/ipv6/ndisc.c +1 -2
@@ -586,6 +586,7 @@ static void ndisc_send_na(struct net_dev
  		src_addr = solicited_addr;
  		if (ifp->flags&  IFA_F_OPTIMISTIC)
  			override = 0;
+		inc_opt |= ifp->idev->cnf.force_tllao;
  		in6_ifa_put(ifp);
  	} else {
  		if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
@@ -599,7 +600,6 @@ static void ndisc_send_na(struct net_dev
  	icmp6h.icmp6_solicited = solicited;
  	icmp6h.icmp6_override = override;
 
-	inc_opt |= ifp->idev->cnf.force_tllao;
  	__ndisc_send(dev, neigh, daddr, src_addr,
  		&icmp6h, solicited_addr,
  		     inc_opt ? ND_OPT_TARGET_LL_ADDR : 0);
--

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

maintainer Applied
#9 lore raw

Re: [PATCH] ipv6: fix NULL reference in proxy neighbor discovery

In reply to Stephen Hemminger

From: Stephen Hemminger <[email protected]>
Date: Mon, 21 Jun 2010 14:00:13 -0700

Quoted 5 lines

The addition of TLLAO option created a kernel OOPS regression for the case where neighbor advertisement is being sent via proxy path. When using proxy, ipv6_get_ifaddr() returns NULL causing the NULL dereference.

Quoted 8 lines

Change causing the bug was:
commit f7734fdf61ec6bb848e0bafc1fb8bad2c124bb50

Author: Octavian Purdila <[email protected]>
Date:   Fri Oct 2 11:39:15 2009 +0000

make TLLAO option for NA packets configurable

Applied, thanks.

#10 lore raw
In reply to Andreas Klauer
Quoted 2 lines · Andreas Klauer

Thanks a lot! This fix seems to work fine for me (tested locally only). I'll see what happens when I apply it to my server tomorrow.

The fix also works for my server.

Thank you
Andreas Klauer