netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 2/3] IPV6: unify 3 similar code path in ndisc_recv_ns()
@ 2004-02-06  9:10 YOSHIFUJI Hideaki / 吉藤英明
  2004-02-06 23:32 ` David S. Miller
  0 siblings, 1 reply; 3+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-02-06  9:10 UTC (permalink / raw)
  To: davem; +Cc: yoshfuji, netdev

Hello.

[PATCH 2/3] IPV6: unify 3 similar code path in ndisc_recv_ns()

D: Unify 3 similar code path in ndisc_recv_ns().
D: This patch also fixes:
D:  - flags sent with NA in reply to this NS
D:  - missing random delay after receipt of NS against anycast

Thanks.

--- linux26-dad/net/ipv6/ndisc.c	Fri Feb  6 15:12:33 2004
+++ linux26-recv_ns/net/ipv6/ndisc.c	Fri Feb  6 16:38:16 2004
@@ -707,8 +707,10 @@ static void ndisc_recv_ns(struct sk_buff
 	struct ndisc_options ndopts;
 	struct net_device *dev = skb->dev;
 	struct inet6_ifaddr *ifp;
+	struct inet6_dev *idev = NULL;
 	struct neighbour *neigh;
 	int addr_type = ipv6_addr_type(saddr);
+	int inc;
 
 	if (ipv6_addr_is_multicast(&msg->target)) {
 		if (net_ratelimit())
@@ -757,6 +759,8 @@ static void ndisc_recv_ns(struct sk_buff
 		}
 	}
 
+	inc = ipv6_addr_is_multicast(daddr);
+
 	if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1)) != NULL) {
 		if (ifp->flags & IFA_F_TENTATIVE) {
 			/* Address is tentative. If the source
@@ -784,127 +788,72 @@ static void ndisc_recv_ns(struct sk_buff
 			addrconf_dad_failure(ifp); 
 			return;
 		}
-	
-		if (addr_type == IPV6_ADDR_ANY) {
-			struct in6_addr maddr;
 
-			ipv6_addr_all_nodes(&maddr);
-			ndisc_send_na(dev, NULL, &maddr, &ifp->addr, 
-				      ifp->idev->cnf.forwarding, 0, 
-				      1, 1);
-			in6_ifa_put(ifp);
+		idev = ifp->idev;
+	} else {
+		idev = in6_dev_get(dev);
+		if (!idev) {
+			/* XXX: count this drop? */
 			return;
 		}
 
-		if (addr_type & IPV6_ADDR_UNICAST) {
-			if (ipv6_addr_is_multicast(daddr))
-				nd_tbl.stats.rcv_probes_mcast++;
-			else
-				nd_tbl.stats.rcv_probes_ucast++;
-
-			/* 
-			 *	update / create cache entry
-			 *	for the source address
-			 */
+		if (ipv6_chk_acast_addr(dev, &msg->target) ||
+		    (idev->cnf.forwarding && 
+		     pneigh_lookup(&nd_tbl, &msg->target, dev, 0))) {
+			if (skb->stamp.tv_sec != 0 &&
+			    skb->pkt_type != PACKET_HOST &&
+			    inc != 0 &&
+			    idev->nd_parms->proxy_delay != 0) {
+				/*
+				 * for anycast or proxy,
+				 * sender should delay its response 
+				 * by a random time between 0 and 
+				 * MAX_ANYCAST_DELAY_TIME seconds.
+				 * (RFC2461) -- yoshfuji
+				 */
+				struct sk_buff *n = skb_clone(skb, GFP_ATOMIC);
+				if (n)
+					pneigh_enqueue(&nd_tbl, idev->nd_parms, n);
+				goto out;
+			}
+		} else
+			goto out;
+	}
 
-			neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, dev);
+	if (addr_type == IPV6_ADDR_ANY) {
+		struct in6_addr maddr;
 
-			if (neigh || !dev->hard_header) {
-				ndisc_send_na(dev, neigh, saddr, &ifp->addr, 
-					      ifp->idev->cnf.forwarding, 1, 
-					      1, 1);
-				if (neigh)
-					neigh_release(neigh);
-			}
-		}
-		in6_ifa_put(ifp);
-	} else if (ipv6_chk_acast_addr(dev, &msg->target)) {
-		struct inet6_dev *idev = in6_dev_get(dev);
-	
-		/* anycast */
-	
-		if (!idev) {
-			/* XXX: count this drop? */
-			return;
-		}
-	
-		if (addr_type == IPV6_ADDR_ANY) {
-			struct in6_addr maddr;
-	
-			ipv6_addr_all_nodes(&maddr);
-			ndisc_send_na(dev, NULL, &maddr, &msg->target,
-				      idev->cnf.forwarding, 0, 0, 1);
-			in6_dev_put(idev);
-			return;
-		}
+		ipv6_addr_all_nodes(&maddr);
+		ndisc_send_na(dev, NULL, &maddr, &msg->target,
+			      idev->cnf.forwarding, 0, (ifp != NULL), 1);
+		goto out;
+	}
 
-		if (addr_type & IPV6_ADDR_UNICAST) {
-			int inc = ipv6_addr_is_multicast(daddr);
-			if (inc)  
-				nd_tbl.stats.rcv_probes_mcast++;
-			else
-				nd_tbl.stats.rcv_probes_ucast++;
-	
-			/*
-			 *   update / create cache entry
-			 *   for the source address
-			 */
+	if (inc)
+		nd_tbl.stats.rcv_probes_mcast++;
+	else
+		nd_tbl.stats.rcv_probes_ucast++;
+
+	/* 
+	 *	update / create cache entry
+	 *	for the source address
+	 */
+	neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, dev);
 
-			neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, skb->dev);
+	if (neigh || !dev->hard_header) {
+		ndisc_send_na(dev, neigh, saddr, &msg->target,
+			      idev->cnf.forwarding, 
+			      1, (ifp != NULL && inc), inc);
+		if (neigh)
+			neigh_release(neigh);
+	}
 
-			if (neigh || !dev->hard_header) {
-				ndisc_send_na(dev, neigh, saddr,
-					      &msg->target, 
-					      idev->cnf.forwarding, 1, 0, inc);
-				if (neigh)
-					neigh_release(neigh);
-			}
-		}
+out:
+	if (ifp)
+		in6_ifa_put(ifp);
+	else
 		in6_dev_put(idev);
-	} else {
-		struct inet6_dev *in6_dev = in6_dev_get(dev);
 
-		if (in6_dev && in6_dev->cnf.forwarding &&
-		    (addr_type & IPV6_ADDR_UNICAST ||
-		     addr_type == IPV6_ADDR_ANY) &&
-		    pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) {
-			int inc = ipv6_addr_is_multicast(daddr);
-
-			if (skb->stamp.tv_sec == 0 ||
-			    skb->pkt_type == PACKET_HOST ||
-			    inc == 0 ||
-			    in6_dev->nd_parms->proxy_delay == 0) {
-				if (inc)
-					nd_tbl.stats.rcv_probes_mcast++;
-				else
-					nd_tbl.stats.rcv_probes_ucast++;
-					
-				if (addr_type & IPV6_ADDR_UNICAST) {
-					neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, dev);
-
-					if (neigh) {
-						ndisc_send_na(dev, neigh, saddr, &msg->target,
-							      0, 1, 0, 1);
-						neigh_release(neigh);
-					}
-				} else {
-					/* proxy should also protect against DAD */
-					struct in6_addr maddr;
-					ipv6_addr_all_nodes(&maddr);
-					ndisc_send_na(dev, NULL, &maddr, &msg->target, 
-						      0, 0, 0, 1);
-				}
-			} else {
-				struct sk_buff *n = skb_clone(skb, GFP_ATOMIC);
-				if (n)
-					pneigh_enqueue(&nd_tbl, in6_dev->nd_parms, n);
-				in6_dev_put(in6_dev);
-				return;
-			}
-		}
-		if (in6_dev)
-			in6_dev_put(in6_dev);
-	}
 	return;
 }
 

-- 
Hideaki YOSHIFUJI @ USAGI Project <yoshfuji@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF  80D8 4807 F894 E062 0EEA

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2004-02-07  5:17 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-02-06  9:10 [PATCH 2/3] IPV6: unify 3 similar code path in ndisc_recv_ns() YOSHIFUJI Hideaki / 吉藤英明
2004-02-06 23:32 ` David S. Miller
2004-02-07  5:17   ` Arnaldo Carvalho de Melo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).