Sophie

Sophie

distrib > CentOS > 5 > x86_64 > by-pkgid > ea32411352494358b8d75a78402a4713 > files > 2873

kernel-2.6.18-238.19.1.el5.centos.plus.src.rpm

From: Thomas Graf <tgraf@redhat.com>
Date: Thu, 26 Aug 2010 09:00:38 -0400
Subject: [net] ipv6: Update Neighbor Cache when IPv6 RA received
Message-id: <20100826090038.GB14555@lsx.localdomain>
Patchwork-id: 27821
O-Subject: [RHEL5.6 PATCH] ipv6: Update Neighbor Cache when IPv6 RA is received
	on a router (BZ560870)
Bugzilla: 560870
RH-Acked-by: Neil Horman <nhorman@redhat.com>
RH-Acked-by: David S. Miller <davem@redhat.com>
RH-Acked-by: Jiri Pirko <jpirko@redhat.com>

Straight backport of commit
31ce8c71a3bdab12debb5899b1f6dac13e54c71d:

When processing a received IPv6 Router Advertisement, the kernel
creates or updates an IPv6 Neighbor Cache entry for the sender --
but presently this does not occur if IPv6 forwarding is enabled
(net.ipv6.conf.*.forwarding = 1), or if IPv6 Router Advertisements
are not accepted (net.ipv6.conf.*.accept_ra = 0), because in these
cases processing of the Router Advertisement has already halted.

This patch allows the Neighbor Cache to be updated in these cases,
while still avoiding any modification to routes or link parameters.

This continues to satisfy RFC 4861, since any entry created in the
Neighbor Cache as the result of a received Router Advertisement is
still placed in the STALE state.

Signed-off-by: David Ward <david.ward@ll.mit.edu>
Signed-off-by: David S. Miller <davem@davemloft.net>

Tested by me and the reporter.

Resolves BZ560870

Signed-off-by: Jarod Wilson <jarod@redhat.com>

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 22be73f..04e7f74 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1230,10 +1230,6 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 			   skb->dev->name);
 		return;
 	}
-	if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) {
-		in6_dev_put(in6_dev);
-		return;
-	}
 
 	if (!ndisc_parse_options(opt, optlen, &ndopts)) {
 		in6_dev_put(in6_dev);
@@ -1242,6 +1238,9 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 		return;
 	}
 
+	if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra)
+		goto skip_linkparms;
+
 	if (in6_dev->if_flags & IF_RS_SENT) {
 		/*
 		 *	flag that an RA was received after an RS was sent
@@ -1356,6 +1355,8 @@ skip_defrtr:
 		}
 	}
 
+skip_linkparms:
+
 	/*
 	 *	Process options.
 	 */
@@ -1381,6 +1382,9 @@ skip_defrtr:
 			     NEIGH_UPDATE_F_ISROUTER);
 	}
 
+	if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra)
+		goto out;
+
 #ifdef CONFIG_IPV6_ROUTE_INFO
 	if (in6_dev->cnf.accept_ra_rtr_pref && ndopts.nd_opts_ri) {
 		struct nd_opt_hdr *p;