aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv6/ndisc.c1
-rw-r--r--net/ipv6/sit.c58
2 files changed, 59 insertions, 0 deletions
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index ab65cc51b00..e09f12ee57c 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 3fd060076e7..b3a59bd40f0 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 }