[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

(usagi-users 02705) Re: insufficient process when receiving IPv6 Router Solicitation



In article <3FE1580C.2080004@xxxxxxxxxxxxxx> (at Thu, 18 Dec 2003 16:32:28 +0900), Hiroaki Kago <kago@xxxxxxxxxxxxxx> says:

> I think that the processing which receives Router Solicitation
> Message is insufficient in the USAGI snap kernel-2.6-s20031208.
:
> I made a patch and fixed the problem. This patch referred
> to the USAGI snap kernel-2.4-s20031208.

Thank you for your notification.
But your patch seems buggy; cannot compile.

> +       neigh = __neigh_lookup(&nd_tbl, saddr, skb->dev, 1);
> +       if (neigh) {
> +               int notify;
> +               write_lock(&neigh->lock);
> +               neigh_update(neigh, lladdr, NUD_STALE, 1, NEIGH_UPDATE_TYPE_IP6RS);
> +               write_unlock(&neigh->lock);
> +#ifdef CONFIG_ARPD
> +               if (notify > 0)
> +                       neigh_app_notify(neigh);
> +#endif
> +               neigh_release(neigh);
> +       }
> +out:
> +       in6_dev_put(idev);

Well, because neigh_update() in usagi-linux24 is very different from
one in 2.6, you cannot use it blindly.

1. neigh_update lock neigh->lock, so dead lock occurs.
2. "notify" is not initialized.
3. because neigh_app_notfiy is done is neigh_update(), so
   you don't need to do it outside.
4. NEIGH_UPDATE_TYPE_IP6RS is not defined.
   
I've committed revised version into our repository.

Index: include/net/ndisc.h
===================================================================
RCS file: /cvsroot/usagi/usagi/kernel/linux26/include/net/ndisc.h,v
retrieving revision 1.4
diff -u -r1.4 ndisc.h
--- include/net/ndisc.h	3 Jul 2003 05:10:39 -0000	1.4
+++ include/net/ndisc.h	18 Dec 2003 09:40:08 -0000
@@ -45,6 +45,11 @@
 	__u8		opt[0];
 };
 
+struct rs_msg {
+	struct icmp6hdr	icmph;
+	__u8		opt[0];
+};
+
 struct ra_msg {
         struct icmp6hdr		icmph;
 	__u32			reachable_time;
Index: net/ipv6/ndisc.c
===================================================================
RCS file: /cvsroot/usagi/usagi/kernel/linux26/net/ipv6/ndisc.c,v
retrieving revision 1.38
diff -u -r1.38 ndisc.c
--- net/ipv6/ndisc.c	12 Dec 2003 14:01:43 -0000	1.38
+++ net/ipv6/ndisc.c	18 Dec 2003 09:40:08 -0000
@@ -999,6 +999,63 @@
 	}
 }
 
+static void ndisc_recv_rs(struct sk_buff *skb)
+{
+	struct rs_msg *rs_msg = (struct rs_msg *) skb->h.raw;
+	unsigned long ndoptlen = skb->len - sizeof(*rs_msg);
+	struct neighbour *neigh;
+	struct inet6_dev *idev;
+	struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
+	struct ndisc_options ndopts;
+	u8 *lladdr = NULL;
+	int lladdrlen = 0;
+
+	if (skb->len < sizeof(*rs_msg))
+		return;
+
+	idev = in6_dev_get(skb->dev);
+	if (!idev) {
+		if (net_ratelimit())
+			ND_PRINTK1(KERN_WARNING
+					"ICMP6 RS: can't find in6 device\n");
+		return;
+	}
+
+	/* Don't accept RS if we're not in router mode */
+	if (!idev->cnf.forwarding || idev->cnf.accept_ra)
+		goto out;
+
+	/*
+	 * Don't update NCE if src = ::;
+	 * this implies that the source node has no ip address assigned yet.
+	 */
+	if (ipv6_addr_any(saddr))
+		goto out;
+
+	/* Parse ND options */
+	if (!ndisc_parse_options(rs_msg->opt, ndoptlen, &ndopts)) {
+		if (net_ratelimit())
+			ND_PRINTK2(KERN_WARNING
+					"ICMP6 NS: invalid ND option, ignored\n");
+		goto out;
+	}
+
+	if (ndopts.nd_opts_src_lladdr) {
+		lladdr = (u8 *)(ndopts.nd_opts_src_lladdr + 1);
+		lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
+		if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len))
+			goto out;
+	}
+
+	neigh = __neigh_lookup(&nd_tbl, saddr, skb->dev, 1);
+	if (neigh) {
+		neigh_update(neigh, lladdr, NUD_STALE, 1, 1);
+		neigh_release(neigh);
+	}
+out:
+	in6_dev_put(idev);
+}
+
 static void ndisc_router_discovery(struct sk_buff *skb)
 {
         struct ra_msg *ra_msg = (struct ra_msg *) skb->h.raw;
@@ -1474,6 +1531,10 @@
 		ndisc_recv_na(skb);
 		break;
 
+	case NDISC_ROUTER_SOLICITATION:
+		ndisc_recv_rs(skb);
+		break;
+
 	case NDISC_ROUTER_ADVERTISEMENT:
 		ndisc_router_discovery(skb);
 		break;

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