aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hlusiak <contact@saschahlusiak.de>2009-05-19 08:56:52 -0400
committerDavid S. Miller <davem@davemloft.net>2009-05-19 19:02:02 -0400
commit645069299a1c7358cf7330afe293f07552f11a5d (patch)
tree889c39a10ef09cd77c5b052ef837bb4b53bddd83
parent9af28511be10e175eb0cabb2ba5cfafe77408d84 (diff)
sit: stateless autoconf for isatap
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> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/if_tunnel.h2
-rw-r--r--include/net/ipip.h7
-rw-r--r--net/ipv6/ndisc.c1
-rw-r--r--net/ipv6/sit.c58
4 files changed, 67 insertions, 1 deletions
diff --git a/include/linux/if_tunnel.h b/include/linux/if_tunnel.h
index 5a9aae4adb44..5eb9b0f857e0 100644
--- a/include/linux/if_tunnel.h
+++ b/include/linux/if_tunnel.h
@@ -44,7 +44,7 @@ struct ip_tunnel_prl {
44 __u16 flags; 44 __u16 flags;
45 __u16 __reserved; 45 __u16 __reserved;
46 __u32 datalen; 46 __u32 datalen;
47 __u32 __reserved2; 47 __u32 rs_delay;
48 /* data follows */ 48 /* data follows */
49}; 49};
50 50
diff --git a/include/net/ipip.h b/include/net/ipip.h
index fdf9bd743705..5d3036fa1511 100644
--- a/include/net/ipip.h
+++ b/include/net/ipip.h
@@ -28,11 +28,18 @@ struct ip_tunnel
28 unsigned int prl_count; /* # of entries in PRL */ 28 unsigned int prl_count; /* # of entries in PRL */
29}; 29};
30 30
31/* ISATAP: default interval between RS in secondy */
32#define IPTUNNEL_RS_DEFAULT_DELAY (900)
33
31struct ip_tunnel_prl_entry 34struct ip_tunnel_prl_entry
32{ 35{
33 struct ip_tunnel_prl_entry *next; 36 struct ip_tunnel_prl_entry *next;
34 __be32 addr; 37 __be32 addr;
35 u16 flags; 38 u16 flags;
39 unsigned long rs_delay;
40 struct timer_list rs_timer;
41 struct ip_tunnel *tunnel;
42 spinlock_t lock;
36}; 43};
37 44
38#define IPTUNNEL_XMIT() do { \ 45#define IPTUNNEL_XMIT() do { \
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index ab65cc51b00e..e09f12ee57cf 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,
658 &icmp6h, NULL, 658 &icmp6h, NULL,
659 send_sllao ? ND_OPT_SOURCE_LL_ADDR : 0); 659 send_sllao ? ND_OPT_SOURCE_LL_ADDR : 0);
660} 660}
661EXPORT_SYMBOL(ndisc_send_rs);
661 662
662 663
663static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb) 664static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb)
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 3fd060076e7a..b3a59bd40f01 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -15,6 +15,7 @@
15 * Roger Venning <r.venning@telstra.com>: 6to4 support 15 * Roger Venning <r.venning@telstra.com>: 6to4 support
16 * Nate Thompson <nate@thebog.net>: 6to4 support 16 * Nate Thompson <nate@thebog.net>: 6to4 support
17 * Fred Templin <fred.l.templin@boeing.com>: isatap support 17 * Fred Templin <fred.l.templin@boeing.com>: isatap support
18 * Sascha Hlusiak <mail@saschahlusiak.de>: stateless autoconf for isatap
18 */ 19 */
19 20
20#include <linux/module.h> 21#include <linux/module.h>
@@ -222,6 +223,44 @@ failed:
222 return NULL; 223 return NULL;
223} 224}
224 225
226static void ipip6_tunnel_rs_timer(unsigned long data)
227{
228 struct ip_tunnel_prl_entry *p = (struct ip_tunnel_prl_entry *) data;
229 struct inet6_dev *ifp;
230 struct inet6_ifaddr *addr;
231
232 spin_lock(&p->lock);
233 ifp = __in6_dev_get(p->tunnel->dev);
234
235 read_lock_bh(&ifp->lock);
236 for (addr = ifp->addr_list; addr; addr = addr->if_next) {
237 struct in6_addr rtr;
238
239 if (!(ipv6_addr_type(&addr->addr) & IPV6_ADDR_LINKLOCAL))
240 continue;
241
242 /* Send RS to guessed linklocal address of router
243 *
244 * Better: send to ff02::2 encapsuled in unicast directly
245 * to router-v4 instead of guessing the v6 address.
246 *
247 * Cisco/Windows seem to not set the u/l bit correctly,
248 * so we won't guess right.
249 */
250 ipv6_addr_set(&rtr, htonl(0xFE800000), 0, 0, 0);
251 if (!__ipv6_isatap_ifid(rtr.s6_addr + 8,
252 p->addr)) {
253 ndisc_send_rs(p->tunnel->dev, &addr->addr, &rtr);
254 }
255 }
256 read_unlock_bh(&ifp->lock);
257
258 mod_timer(&p->rs_timer, jiffies + HZ * p->rs_delay);
259 spin_unlock(&p->lock);
260
261 return;
262}
263
225static struct ip_tunnel_prl_entry * 264static struct ip_tunnel_prl_entry *
226__ipip6_tunnel_locate_prl(struct ip_tunnel *t, __be32 addr) 265__ipip6_tunnel_locate_prl(struct ip_tunnel *t, __be32 addr)
227{ 266{
@@ -280,6 +319,7 @@ static int ipip6_tunnel_get_prl(struct ip_tunnel *t,
280 continue; 319 continue;
281 kp[c].addr = prl->addr; 320 kp[c].addr = prl->addr;
282 kp[c].flags = prl->flags; 321 kp[c].flags = prl->flags;
322 kp[c].rs_delay = prl->rs_delay;
283 c++; 323 c++;
284 if (kprl.addr != htonl(INADDR_ANY)) 324 if (kprl.addr != htonl(INADDR_ANY))
285 break; 325 break;
@@ -329,11 +369,23 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg)
329 } 369 }
330 370
331 p->next = t->prl; 371 p->next = t->prl;
372 p->tunnel = t;
332 t->prl = p; 373 t->prl = p;
333 t->prl_count++; 374 t->prl_count++;
375
376 spin_lock_init(&p->lock);
377 setup_timer(&p->rs_timer, ipip6_tunnel_rs_timer, (unsigned long) p);
334update: 378update:
335 p->addr = a->addr; 379 p->addr = a->addr;
336 p->flags = a->flags; 380 p->flags = a->flags;
381 p->rs_delay = a->rs_delay;
382 if (p->rs_delay == 0)
383 p->rs_delay = IPTUNNEL_RS_DEFAULT_DELAY;
384 spin_lock(&p->lock);
385 del_timer(&p->rs_timer);
386 if (p->flags & PRL_DEFAULT)
387 mod_timer(&p->rs_timer, jiffies + 1);
388 spin_unlock(&p->lock);
337out: 389out:
338 write_unlock(&ipip6_lock); 390 write_unlock(&ipip6_lock);
339 return err; 391 return err;
@@ -352,6 +404,9 @@ ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a)
352 if ((*p)->addr == a->addr) { 404 if ((*p)->addr == a->addr) {
353 x = *p; 405 x = *p;
354 *p = x->next; 406 *p = x->next;
407 spin_lock(&x->lock);
408 del_timer(&x->rs_timer);
409 spin_unlock(&x->lock);
355 kfree(x); 410 kfree(x);
356 t->prl_count--; 411 t->prl_count--;
357 goto out; 412 goto out;
@@ -362,6 +417,9 @@ ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a)
362 while (t->prl) { 417 while (t->prl) {
363 x = t->prl; 418 x = t->prl;
364 t->prl = t->prl->next; 419 t->prl = t->prl->next;
420 spin_lock(&x->lock);
421 del_timer(&x->rs_timer);
422 spin_unlock(&x->lock);
365 kfree(x); 423 kfree(x);
366 t->prl_count--; 424 t->prl_count--;
367 } 425 }