Patchwork [5/5] sit: stateless autoconf for isatap

login
register
mail settings
Submitter Sascha Hlusiak
Date May 19, 2009, 9:03 p.m.
Message ID <1242767023-9501-5-git-send-email-contact@saschahlusiak.de>
Download mbox | patch
Permalink /patch/27424/
State Rejected
Delegated to: David Miller
Headers show

Comments

Sascha Hlusiak - May 19, 2009, 9:03 p.m.
From each potential router in the PRL, a router solicitation will
be sent periodically. The rs_delay can be speficied when adding the
PRL entry and defaults to 15 minutes.

The RS is sent from every link local adress that's assigned to the
tunnel interface. It's directed to the (guessed) linklocal address
of the router and is sent through the tunnel.

Better: send to ff02::2 encapsuled in unicast directed to router-v4.

Signed-off-by: Sascha Hlusiak <contact@saschahlusiak.de>
---
 include/linux/if_tunnel.h |    2 +-
 include/net/ipip.h        |    7 +++++
 net/ipv6/ndisc.c          |    1 +
 net/ipv6/sit.c            |   58 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 67 insertions(+), 1 deletions(-)
David Miller - May 19, 2009, 9:35 p.m.
From: Sascha Hlusiak <contact@saschahlusiak.de>

Date: Tue, 19 May 2009 23:03:43 +0200

> +	spin_lock(&ifp->lock);

> +	for (addr = ifp->addr_list; addr; addr = addr->if_next) {


You posted the same broken patch again!

net/ipv6/sit.c: In function ‘ipip6_tunnel_rs_timer’:
net/ipv6/sit.c:235: warning: passing argument 1 of ‘_spin_lock’ from incompatible pointer type
net/ipv6/sit.c:256: warning: passing argument 1 of ‘__raw_spin_unlock’ from incompatible pointer type

This isn't rocket science. :-/
Sascha Hlusiak - May 19, 2009, 10:57 p.m.
> > +	spin_lock(&ifp->lock);
> > +	for (addr = ifp->addr_list; addr; addr = addr->if_next) {
>
> You posted the same broken patch again!
>
> net/ipv6/sit.c: In function ‘ipip6_tunnel_rs_timer’:
> net/ipv6/sit.c:235: warning: passing argument 1 of ‘_spin_lock’ from
> incompatible pointer type net/ipv6/sit.c:256: warning: passing argument 1
> of ‘__raw_spin_unlock’ from incompatible pointer type
>
> This isn't rocket science. :-/
Sorry, I overlooked I had CONFIT_DEBUG_SPINLOCK unset so the above lines 
weren't even compiled.

I'm really sorry for all the noise and hope the latest resent patchset is 
finally correct. Thanks for your work.

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/include/linux/if_tunnel.h b/include/linux/if_tunnel.h
index 5a9aae4..5eb9b0f 100644
--- a/include/linux/if_tunnel.h
+++ b/include/linux/if_tunnel.h
@@ -44,7 +44,7 @@  struct ip_tunnel_prl {
 	__u16			flags;
 	__u16			__reserved;
 	__u32			datalen;
-	__u32			__reserved2;
+	__u32			rs_delay;
 	/* data follows */
 };
 
diff --git a/include/net/ipip.h b/include/net/ipip.h
index fdf9bd7..5d3036f 100644
--- a/include/net/ipip.h
+++ b/include/net/ipip.h
@@ -28,11 +28,18 @@  struct ip_tunnel
 	unsigned int			prl_count;	/* # of entries in PRL */
 };
 
+/* ISATAP: default interval between RS in secondy */
+#define IPTUNNEL_RS_DEFAULT_DELAY	(900)
+
 struct ip_tunnel_prl_entry
 {
 	struct ip_tunnel_prl_entry	*next;
 	__be32				addr;
 	u16				flags;
+	unsigned long			rs_delay;
+	struct timer_list		rs_timer;
+	struct ip_tunnel		*tunnel;
+	spinlock_t			lock;
 };
 
 #define IPTUNNEL_XMIT() do {						\
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 9f061d1..f787ac4 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -658,6 +658,7 @@  void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
 		     &icmp6h, NULL,
 		     send_sllao ? ND_OPT_SOURCE_LL_ADDR : 0);
 }
+EXPORT_SYMBOL(ndisc_send_rs);
 
 
 static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb)
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 3fd0600..0535809 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -15,6 +15,7 @@ 
  * Roger Venning <r.venning@telstra.com>:	6to4 support
  * Nate Thompson <nate@thebog.net>:		6to4 support
  * Fred Templin <fred.l.templin@boeing.com>:	isatap support
+ * Sascha Hlusiak <mail@saschahlusiak.de>:	stateless autoconf for isatap
  */
 
 #include <linux/module.h>
@@ -222,6 +223,44 @@  failed:
 	return NULL;
 }
 
+static void ipip6_tunnel_rs_timer(unsigned long data)
+{
+	struct ip_tunnel_prl_entry *p = (struct ip_tunnel_prl_entry *) data;
+	struct inet6_dev *ifp;
+	struct inet6_ifaddr *addr;
+
+	spin_lock(&p->lock);
+	ifp = __in6_dev_get(p->tunnel->dev);
+
+	spin_lock(&ifp->lock);
+	for (addr = ifp->addr_list; addr; addr = addr->if_next) {
+		struct in6_addr rtr;
+
+		if (!(ipv6_addr_type(&addr->addr) & IPV6_ADDR_LINKLOCAL))
+			continue;
+
+		/* Send RS to guessed linklocal address of router
+		 *
+		 * Better: send to ff02::2 encapsuled in unicast directly
+		 * to router-v4 instead of guessing the v6 address.
+		 *
+		 * Cisco/Windows seem to not set the u/l bit correctly,
+		 * so we won't guess right.
+		 */
+		ipv6_addr_set(&rtr,  htonl(0xFE800000), 0, 0, 0);
+		if (!__ipv6_isatap_ifid(rtr.s6_addr + 8,
+					p->addr)) {
+			ndisc_send_rs(p->tunnel->dev, &addr->addr, &rtr);
+		}
+	}
+	spin_unlock(&ifp->lock);
+
+	mod_timer(&p->rs_timer, jiffies + HZ * p->rs_delay);
+	spin_unlock(&p->lock);
+
+	return;
+}
+
 static struct ip_tunnel_prl_entry *
 __ipip6_tunnel_locate_prl(struct ip_tunnel *t, __be32 addr)
 {
@@ -280,6 +319,7 @@  static int ipip6_tunnel_get_prl(struct ip_tunnel *t,
 			continue;
 		kp[c].addr = prl->addr;
 		kp[c].flags = prl->flags;
+		kp[c].rs_delay = prl->rs_delay;
 		c++;
 		if (kprl.addr != htonl(INADDR_ANY))
 			break;
@@ -329,11 +369,23 @@  ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg)
 	}
 
 	p->next = t->prl;
+	p->tunnel = t;
 	t->prl = p;
 	t->prl_count++;
+
+	spin_lock_init(&p->lock);
+	setup_timer(&p->rs_timer, ipip6_tunnel_rs_timer, (unsigned long) p);
 update:
 	p->addr = a->addr;
 	p->flags = a->flags;
+	p->rs_delay = a->rs_delay;
+	if (p->rs_delay == 0)
+		p->rs_delay = IPTUNNEL_RS_DEFAULT_DELAY;
+	spin_lock(&p->lock);
+	del_timer(&p->rs_timer);
+	if (p->flags & PRL_DEFAULT)
+		mod_timer(&p->rs_timer, jiffies + 1);
+	spin_unlock(&p->lock);
 out:
 	write_unlock(&ipip6_lock);
 	return err;
@@ -352,6 +404,9 @@  ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a)
 			if ((*p)->addr == a->addr) {
 				x = *p;
 				*p = x->next;
+				spin_lock(&x->lock);
+				del_timer(&x->rs_timer);
+				spin_unlock(&x->lock);
 				kfree(x);
 				t->prl_count--;
 				goto out;
@@ -362,6 +417,9 @@  ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a)
 		while (t->prl) {
 			x = t->prl;
 			t->prl = t->prl->next;
+			spin_lock(&x->lock);
+			del_timer(&x->rs_timer);
+			spin_unlock(&x->lock);
 			kfree(x);
 			t->prl_count--;
 		}