aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/sit.c
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 /net/ipv6/sit.c
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>
Diffstat (limited to 'net/ipv6/sit.c')
-rw-r--r--net/ipv6/sit.c58
1 files changed, 58 insertions, 0 deletions
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 }