Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 2774

kernel-2.6.18-238.el5.src.rpm

From: Neil Horman <nhorman@redhat.com>
Date: Wed, 27 Aug 2008 10:07:00 -0400
Subject: [net] ipv6: drop outside of box loopback address packets
Message-id: 20080827140700.GA17211@hmsendeavour.rdu.redhat.com
O-Subject: [RHEL 5.3 PATCH] ipv6: drop frames with a loopback dst addr on non-loopback interfaces (bz 459556)
Bugzilla: 459556
RH-Acked-by: David Miller <davem@redhat.com>
RH-Acked-by: Jiri Pirko <jpirko@redhat.com>

Hey-
	Backport of upstream commit f630e43a215a3129d0c1173cae0bce6ea4855cf7
Adds code to drop frames with a loopback dst addr if they arrive on a
non-loopback interface.  Tested successfully by our QA guys.  Fixes bz 459556
and TAHI test case "ICMPv6 test v6LC.5.1.2 Part F".

Regards
Neil

diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index c855f60..37638dd 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -383,6 +383,12 @@ static inline int ipv6_addr_any(const struct in6_addr *a)
 		 a->s6_addr32[2] | a->s6_addr32[3] ) == 0); 
 }
 
+static inline int ipv6_addr_loopback(const struct in6_addr *a)
+{
+	return ((a->s6_addr32[0] | a->s6_addr32[1] |
+		a->s6_addr32[2] | (a->s6_addr32[3] ^ htonl(1))) == 0);
+}
+
 /*
  * find the first different bit between two addresses
  * length of address must be a multiple of 32bits
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 7b8d9ac..48bf675 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -102,6 +102,15 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
 	if (hdr->version != 6)
 		goto err;
 
+	/*
+	 * RFC4291 2.5.3
+	 * A packet received on an interface with a destination address
+	 * of loopback must be dropped.
+	 */
+	if (!(dev->flags & IFF_LOOPBACK) &&
+	    ipv6_addr_loopback(&hdr->daddr))
+		goto err;
+ 
 	skb->h.raw = (u8 *)(hdr + 1);
 	IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);