1 /*
2 * Neighbour Discovery for IPv6
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <pedro_m@yahoo.com>
7 * Mike Shaver <shaver@ingenia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 */
14
15 /*
16 * Changes:
17 *
18 * Lars Fenneberg : fixed MTU setting on receipt
19 * of an RA.
20 *
21 * Janos Farkas : kmalloc failure checks
22 * Alexey Kuznetsov : state machine reworked
23 * and moved to net/core.
24 * Pekka Savola : RFC2461 validation
25 * YOSHIFUJI Hideaki @USAGI : Verify ND options properly
26 */
27
28 /* Set to 3 to get tracing... */
29 #define ND_DEBUG 1
30
31 #define ND_PRINTK(x...) printk(KERN_DEBUG x)
32 #define ND_NOPRINTK(x...) do { ; } while(0)
33 #define ND_PRINTK0 ND_PRINTK
34 #define ND_PRINTK1 ND_NOPRINTK
35 #define ND_PRINTK2 ND_NOPRINTK
36 #if ND_DEBUG >= 1
37 #undef ND_PRINTK1
38 #define ND_PRINTK1 ND_PRINTK
39 #endif
40 #if ND_DEBUG >= 2
41 #undef ND_PRINTK2
42 #define ND_PRINTK2 ND_PRINTK
43 #endif
44
45 #include <linux/module.h>
46 #include <linux/config.h>
47 #include <linux/errno.h>
48 #include <linux/types.h>
49 #include <linux/socket.h>
50 #include <linux/sockios.h>
51 #include <linux/sched.h>
52 #include <linux/net.h>
53 #include <linux/in6.h>
54 #include <linux/route.h>
55 #include <linux/init.h>
56 #ifdef CONFIG_SYSCTL
57 #include <linux/sysctl.h>
58 #endif
59
60 #include <linux/if_arp.h>
61 #include <linux/ipv6.h>
62 #include <linux/icmpv6.h>
63 #include <linux/jhash.h>
64
65 #include <net/sock.h>
66 #include <net/snmp.h>
67
68 #include <net/ipv6.h>
69 #include <net/protocol.h>
70 #include <net/ndisc.h>
71 #include <net/ip6_route.h>
72 #include <net/addrconf.h>
73 #include <net/icmp.h>
74
75 #include <net/checksum.h>
76 #include <linux/proc_fs.h>
77
78 static struct socket *ndisc_socket;
79
80 static u32 ndisc_hash(const void *pkey, const struct net_device *dev);
81 static int ndisc_constructor(struct neighbour *neigh);
82 static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb);
83 static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb);
84 static int pndisc_constructor(struct pneigh_entry *n);
85 static void pndisc_destructor(struct pneigh_entry *n);
86 static void pndisc_redo(struct sk_buff *skb);
87
88 static struct neigh_ops ndisc_generic_ops =
89 {
90 AF_INET6,
91 NULL,
92 ndisc_solicit,
93 ndisc_error_report,
94 neigh_resolve_output,
95 neigh_connected_output,
96 dev_queue_xmit,
97 dev_queue_xmit
98 };
99
100 static struct neigh_ops ndisc_hh_ops =
101 {
102 AF_INET6,
103 NULL,
104 ndisc_solicit,
105 ndisc_error_report,
106 neigh_resolve_output,
107 neigh_resolve_output,
108 dev_queue_xmit,
109 dev_queue_xmit
110 };
111
112
113 static struct neigh_ops ndisc_direct_ops =
114 {
115 AF_INET6,
116 NULL,
117 NULL,
118 NULL,
119 dev_queue_xmit,
120 dev_queue_xmit,
121 dev_queue_xmit,
122 dev_queue_xmit
123 };
124
125 struct neigh_table nd_tbl =
126 {
127 NULL,
128 AF_INET6,
129 sizeof(struct neighbour) + sizeof(struct in6_addr),
130 sizeof(struct in6_addr),
131 ndisc_hash,
132 ndisc_constructor,
133 pndisc_constructor,
134 pndisc_destructor,
135 pndisc_redo,
136 "ndisc_cache",
137 { NULL, NULL, &nd_tbl, 0, NULL, NULL,
138 30*HZ, 1*HZ, 60*HZ, 30*HZ, 5*HZ, 3, 3, 0, 3, 1*HZ, (8*HZ)/10, 64, 0 },
139 30*HZ, 128, 512, 1024,
140 };
141
142 #define NDISC_OPT_SPACE(len) (((len)+2+7)&~7)
143
ndisc_fill_option(u8 * opt,int type,void * data,int data_len)144 static u8 *ndisc_fill_option(u8 *opt, int type, void *data, int data_len)
145 {
146 int space = NDISC_OPT_SPACE(data_len);
147
148 opt[0] = type;
149 opt[1] = space>>3;
150 memcpy(opt+2, data, data_len);
151 data_len += 2;
152 opt += data_len;
153 if ((space -= data_len) > 0)
154 memset(opt, 0, space);
155 return opt + space;
156 }
157
ndisc_next_option(struct nd_opt_hdr * cur,struct nd_opt_hdr * end)158 struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
159 struct nd_opt_hdr *end)
160 {
161 int type;
162 if (!cur || !end || cur >= end)
163 return NULL;
164 type = cur->nd_opt_type;
165 do {
166 cur = ((void *)cur) + (cur->nd_opt_len << 3);
167 } while(cur < end && cur->nd_opt_type != type);
168 return (cur <= end && cur->nd_opt_type == type ? cur : NULL);
169 }
170
ndisc_parse_options(u8 * opt,int opt_len,struct ndisc_options * ndopts)171 struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
172 struct ndisc_options *ndopts)
173 {
174 struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)opt;
175
176 if (!nd_opt || opt_len < 0 || !ndopts)
177 return NULL;
178 memset(ndopts, 0, sizeof(*ndopts));
179 while (opt_len) {
180 int l;
181 if (opt_len < sizeof(struct nd_opt_hdr))
182 return NULL;
183 l = nd_opt->nd_opt_len << 3;
184 if (opt_len < l || l == 0)
185 return NULL;
186 switch (nd_opt->nd_opt_type) {
187 case ND_OPT_SOURCE_LL_ADDR:
188 case ND_OPT_TARGET_LL_ADDR:
189 case ND_OPT_MTU:
190 case ND_OPT_REDIRECT_HDR:
191 if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
192 ND_PRINTK2((KERN_WARNING
193 "ndisc_parse_options(): duplicated ND6 option found: type=%d\n",
194 nd_opt->nd_opt_type));
195 } else {
196 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
197 }
198 break;
199 case ND_OPT_PREFIX_INFO:
200 ndopts->nd_opts_pi_end = nd_opt;
201 if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0)
202 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
203 break;
204 default:
205 /*
206 * Unknown options must be silently ignored,
207 * to accomodate future extension to the protocol.
208 */
209 ND_PRINTK2(KERN_WARNING
210 "ndisc_parse_options(): ignored unsupported option; type=%d, len=%d\n",
211 nd_opt->nd_opt_type, nd_opt->nd_opt_len);
212 }
213 opt_len -= l;
214 nd_opt = ((void *)nd_opt) + l;
215 }
216 return ndopts;
217 }
218
ndisc_mc_map(struct in6_addr * addr,char * buf,struct net_device * dev,int dir)219 int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir)
220 {
221 switch (dev->type) {
222 case ARPHRD_ETHER:
223 case ARPHRD_IEEE802: /* Not sure. Check it later. --ANK */
224 case ARPHRD_FDDI:
225 ipv6_eth_mc_map(addr, buf);
226 return 0;
227 case ARPHRD_IEEE802_TR:
228 ipv6_tr_mc_map(addr,buf);
229 return 0;
230 case ARPHRD_ARCNET:
231 ipv6_arcnet_mc_map(addr, buf);
232 return 0;
233 default:
234 if (dir) {
235 memcpy(buf, dev->broadcast, dev->addr_len);
236 return 0;
237 }
238 }
239 return -EINVAL;
240 }
241
ndisc_hash(const void * pkey,const struct net_device * dev)242 static u32 ndisc_hash(const void *pkey, const struct net_device *dev)
243 {
244 const u32 *p32 = pkey;
245 u32 addr_hash, i;
246
247 addr_hash = 0;
248 for (i = 0; i < (sizeof(struct in6_addr) / sizeof(u32)); i++)
249 addr_hash ^= *p32++;
250
251 return jhash_2words(addr_hash, dev->ifindex, nd_tbl.hash_rnd);
252 }
253
ndisc_constructor(struct neighbour * neigh)254 static int ndisc_constructor(struct neighbour *neigh)
255 {
256 struct in6_addr *addr = (struct in6_addr*)&neigh->primary_key;
257 struct net_device *dev = neigh->dev;
258 struct inet6_dev *in6_dev = in6_dev_get(dev);
259 int addr_type;
260
261 if (in6_dev == NULL)
262 return -EINVAL;
263
264 addr_type = ipv6_addr_type(addr);
265 if (in6_dev->nd_parms)
266 neigh->parms = in6_dev->nd_parms;
267
268 if (addr_type&IPV6_ADDR_MULTICAST)
269 neigh->type = RTN_MULTICAST;
270 else
271 neigh->type = RTN_UNICAST;
272 if (dev->hard_header == NULL) {
273 neigh->nud_state = NUD_NOARP;
274 neigh->ops = &ndisc_direct_ops;
275 neigh->output = neigh->ops->queue_xmit;
276 } else {
277 if (addr_type&IPV6_ADDR_MULTICAST) {
278 neigh->nud_state = NUD_NOARP;
279 ndisc_mc_map(addr, neigh->ha, dev, 1);
280 } else if (dev->flags&(IFF_NOARP|IFF_LOOPBACK)) {
281 neigh->nud_state = NUD_NOARP;
282 memcpy(neigh->ha, dev->dev_addr, dev->addr_len);
283 if (dev->flags&IFF_LOOPBACK)
284 neigh->type = RTN_LOCAL;
285 } else if (dev->flags&IFF_POINTOPOINT) {
286 neigh->nud_state = NUD_NOARP;
287 memcpy(neigh->ha, dev->broadcast, dev->addr_len);
288 }
289 if (dev->hard_header_cache)
290 neigh->ops = &ndisc_hh_ops;
291 else
292 neigh->ops = &ndisc_generic_ops;
293 if (neigh->nud_state&NUD_VALID)
294 neigh->output = neigh->ops->connected_output;
295 else
296 neigh->output = neigh->ops->output;
297 }
298 in6_dev_put(in6_dev);
299 return 0;
300 }
301
pndisc_constructor(struct pneigh_entry * n)302 static int pndisc_constructor(struct pneigh_entry *n)
303 {
304 struct in6_addr *addr = (struct in6_addr*)&n->key;
305 struct in6_addr maddr;
306 struct net_device *dev = n->dev;
307
308 if (dev == NULL || __in6_dev_get(dev) == NULL)
309 return -EINVAL;
310 addrconf_addr_solict_mult(addr, &maddr);
311 ipv6_dev_mc_inc(dev, &maddr);
312 return 0;
313 }
314
pndisc_destructor(struct pneigh_entry * n)315 static void pndisc_destructor(struct pneigh_entry *n)
316 {
317 struct in6_addr *addr = (struct in6_addr*)&n->key;
318 struct in6_addr maddr;
319 struct net_device *dev = n->dev;
320
321 if (dev == NULL || __in6_dev_get(dev) == NULL)
322 return;
323 addrconf_addr_solict_mult(addr, &maddr);
324 ipv6_dev_mc_dec(dev, &maddr);
325 }
326
327
328
329 static int
ndisc_build_ll_hdr(struct sk_buff * skb,struct net_device * dev,struct in6_addr * daddr,struct neighbour * neigh,int len)330 ndisc_build_ll_hdr(struct sk_buff *skb, struct net_device *dev,
331 struct in6_addr *daddr, struct neighbour *neigh, int len)
332 {
333 unsigned char ha[MAX_ADDR_LEN];
334 unsigned char *h_dest = NULL;
335
336 skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
337
338 if (dev->hard_header) {
339 if (ipv6_addr_type(daddr) & IPV6_ADDR_MULTICAST) {
340 ndisc_mc_map(daddr, ha, dev, 1);
341 h_dest = ha;
342 } else if (neigh) {
343 read_lock_bh(&neigh->lock);
344 if (neigh->nud_state&NUD_VALID) {
345 memcpy(ha, neigh->ha, dev->addr_len);
346 h_dest = ha;
347 }
348 read_unlock_bh(&neigh->lock);
349 } else {
350 neigh = neigh_lookup(&nd_tbl, daddr, dev);
351 if (neigh) {
352 read_lock_bh(&neigh->lock);
353 if (neigh->nud_state&NUD_VALID) {
354 memcpy(ha, neigh->ha, dev->addr_len);
355 h_dest = ha;
356 }
357 read_unlock_bh(&neigh->lock);
358 neigh_release(neigh);
359 }
360 }
361
362 if (dev->hard_header(skb, dev, ETH_P_IPV6, h_dest, NULL, len) < 0)
363 return 0;
364 }
365
366 return 1;
367 }
368
369
370 /*
371 * Send a Neighbour Advertisement
372 */
373
ndisc_send_na(struct net_device * dev,struct neighbour * neigh,struct in6_addr * daddr,struct in6_addr * solicited_addr,int router,int solicited,int override,int inc_opt)374 void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
375 struct in6_addr *daddr, struct in6_addr *solicited_addr,
376 int router, int solicited, int override, int inc_opt)
377 {
378 static struct in6_addr tmpaddr;
379 struct inet6_ifaddr *ifp;
380 struct sock *sk = ndisc_socket->sk;
381 struct in6_addr *src_addr;
382 struct nd_msg *msg;
383 int len;
384 struct sk_buff *skb;
385 int err;
386
387 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
388
389 if (inc_opt) {
390 if (dev->addr_len)
391 len += NDISC_OPT_SPACE(dev->addr_len);
392 else
393 inc_opt = 0;
394 }
395
396 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15,
397 1, &err);
398
399 if (skb == NULL) {
400 ND_PRINTK1("send_na: alloc skb failed\n");
401 return;
402 }
403 /* for anycast or proxy, solicited_addr != src_addr */
404 ifp = ipv6_get_ifaddr(solicited_addr, dev);
405 if (ifp) {
406 src_addr = solicited_addr;
407 in6_ifa_put(ifp);
408 } else {
409 if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr, 0))
410 return;
411 src_addr = &tmpaddr;
412 }
413
414 if (ndisc_build_ll_hdr(skb, dev, daddr, neigh, len) == 0) {
415 kfree_skb(skb);
416 return;
417 }
418
419 ip6_nd_hdr(sk, skb, dev, src_addr, daddr, IPPROTO_ICMPV6, len);
420
421 msg = (struct nd_msg *) skb_put(skb, len);
422
423 msg->icmph.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
424 msg->icmph.icmp6_code = 0;
425 msg->icmph.icmp6_cksum = 0;
426
427 msg->icmph.icmp6_unused = 0;
428 msg->icmph.icmp6_router = router;
429 msg->icmph.icmp6_solicited = solicited;
430 msg->icmph.icmp6_override = !!override;
431
432 /* Set the target address. */
433 ipv6_addr_copy(&msg->target, solicited_addr);
434
435 if (inc_opt)
436 ndisc_fill_option(msg->opt, ND_OPT_TARGET_LL_ADDR, dev->dev_addr, dev->addr_len);
437
438 /* checksum */
439 msg->icmph.icmp6_cksum = csum_ipv6_magic(src_addr, daddr, len,
440 IPPROTO_ICMPV6,
441 csum_partial((__u8 *) msg,
442 len, 0));
443
444 dev_queue_xmit(skb);
445
446 ICMP6_INC_STATS(Icmp6OutNeighborAdvertisements);
447 ICMP6_INC_STATS(Icmp6OutMsgs);
448 }
449
ndisc_send_ns(struct net_device * dev,struct neighbour * neigh,struct in6_addr * solicit,struct in6_addr * daddr,struct in6_addr * saddr)450 void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
451 struct in6_addr *solicit,
452 struct in6_addr *daddr, struct in6_addr *saddr)
453 {
454 struct sock *sk = ndisc_socket->sk;
455 struct sk_buff *skb;
456 struct nd_msg *msg;
457 struct in6_addr addr_buf;
458 int len;
459 int err;
460 int send_llinfo;
461
462 if (saddr == NULL) {
463 if (ipv6_get_lladdr(dev, &addr_buf))
464 return;
465 saddr = &addr_buf;
466 }
467
468 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
469 send_llinfo = dev->addr_len && ipv6_addr_type(saddr) != IPV6_ADDR_ANY;
470 if (send_llinfo)
471 len += NDISC_OPT_SPACE(dev->addr_len);
472
473 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15,
474 1, &err);
475 if (skb == NULL) {
476 ND_PRINTK1("send_ns: alloc skb failed\n");
477 return;
478 }
479
480 if (ndisc_build_ll_hdr(skb, dev, daddr, neigh, len) == 0) {
481 kfree_skb(skb);
482 return;
483 }
484
485 ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
486
487 msg = (struct nd_msg *)skb_put(skb, len);
488 msg->icmph.icmp6_type = NDISC_NEIGHBOUR_SOLICITATION;
489 msg->icmph.icmp6_code = 0;
490 msg->icmph.icmp6_cksum = 0;
491 msg->icmph.icmp6_unused = 0;
492
493 /* Set the target address. */
494 ipv6_addr_copy(&msg->target, solicit);
495
496 if (send_llinfo)
497 ndisc_fill_option(msg->opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr, dev->addr_len);
498
499 /* checksum */
500 msg->icmph.icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr,
501 daddr, len,
502 IPPROTO_ICMPV6,
503 csum_partial((__u8 *) msg,
504 len, 0));
505 /* send it! */
506 dev_queue_xmit(skb);
507
508 ICMP6_INC_STATS(Icmp6OutNeighborSolicits);
509 ICMP6_INC_STATS(Icmp6OutMsgs);
510 }
511
ndisc_send_rs(struct net_device * dev,struct in6_addr * saddr,struct in6_addr * daddr)512 void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
513 struct in6_addr *daddr)
514 {
515 struct sock *sk = ndisc_socket->sk;
516 struct sk_buff *skb;
517 struct icmp6hdr *hdr;
518 __u8 * opt;
519 int len;
520 int err;
521
522 len = sizeof(struct icmp6hdr);
523 if (dev->addr_len)
524 len += NDISC_OPT_SPACE(dev->addr_len);
525
526 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15,
527 1, &err);
528 if (skb == NULL) {
529 ND_PRINTK1("send_ns: alloc skb failed\n");
530 return;
531 }
532
533 if (ndisc_build_ll_hdr(skb, dev, daddr, NULL, len) == 0) {
534 kfree_skb(skb);
535 return;
536 }
537
538 ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
539
540 hdr = (struct icmp6hdr *) skb_put(skb, len);
541 hdr->icmp6_type = NDISC_ROUTER_SOLICITATION;
542 hdr->icmp6_code = 0;
543 hdr->icmp6_cksum = 0;
544 hdr->icmp6_unused = 0;
545
546 opt = (u8*) (hdr + 1);
547
548 if (dev->addr_len)
549 ndisc_fill_option(opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr, dev->addr_len);
550
551 /* checksum */
552 hdr->icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr, daddr, len,
553 IPPROTO_ICMPV6,
554 csum_partial((__u8 *) hdr, len, 0));
555
556 /* send it! */
557 dev_queue_xmit(skb);
558
559 ICMP6_INC_STATS(Icmp6OutRouterSolicits);
560 ICMP6_INC_STATS(Icmp6OutMsgs);
561 }
562
563
ndisc_error_report(struct neighbour * neigh,struct sk_buff * skb)564 static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb)
565 {
566 /*
567 * "The sender MUST return an ICMP
568 * destination unreachable"
569 */
570 dst_link_failure(skb);
571 kfree_skb(skb);
572 }
573
574 /* Called with locked neigh: either read or both */
575
ndisc_solicit(struct neighbour * neigh,struct sk_buff * skb)576 static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
577 {
578 struct in6_addr *saddr = NULL;
579 struct in6_addr mcaddr;
580 struct net_device *dev = neigh->dev;
581 struct in6_addr *target = (struct in6_addr *)&neigh->primary_key;
582 int probes = atomic_read(&neigh->probes);
583
584 if (skb && ipv6_chk_addr(&skb->nh.ipv6h->saddr, dev))
585 saddr = &skb->nh.ipv6h->saddr;
586
587 if ((probes -= neigh->parms->ucast_probes) < 0) {
588 if (!(neigh->nud_state&NUD_VALID))
589 ND_PRINTK1("trying to ucast probe in NUD_INVALID\n");
590 ndisc_send_ns(dev, neigh, target, target, saddr);
591 } else if ((probes -= neigh->parms->app_probes) < 0) {
592 #ifdef CONFIG_ARPD
593 neigh_app_ns(neigh);
594 #endif
595 } else {
596 addrconf_addr_solict_mult(target, &mcaddr);
597 ndisc_send_ns(dev, NULL, target, &mcaddr, saddr);
598 }
599 }
600
ndisc_recv_ns(struct sk_buff * skb)601 void ndisc_recv_ns(struct sk_buff *skb)
602 {
603 struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
604 struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
605 struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
606 u8 *lladdr = NULL;
607 int lladdrlen = 0;
608 u32 ndoptlen = skb->tail - msg->opt;
609 struct ndisc_options ndopts;
610 struct net_device *dev = skb->dev;
611 struct inet6_ifaddr *ifp;
612 struct neighbour *neigh;
613
614 if (skb->len < sizeof(struct nd_msg)) {
615 if (net_ratelimit())
616 printk(KERN_WARNING "ICMP NS: packet too short\n");
617 return;
618 }
619
620 if (ipv6_addr_type(&msg->target)&IPV6_ADDR_MULTICAST) {
621 if (net_ratelimit())
622 printk(KERN_WARNING "ICMP NS: target address is multicast\n");
623 return;
624 }
625
626 if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
627 if (net_ratelimit())
628 printk(KERN_WARNING "ICMP NS: invalid ND option, ignored.\n");
629 return;
630 }
631
632 if (ndopts.nd_opts_src_lladdr) {
633 lladdr = (u8*)(ndopts.nd_opts_src_lladdr + 1);
634 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
635 if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len)) {
636 if (net_ratelimit())
637 printk(KERN_WARNING "ICMP NS: bad lladdr length.\n");
638 return;
639 }
640 }
641
642 /* XXX: RFC2461 7.1.1:
643 * If the IP source address is the unspecified address, there
644 * MUST NOT be source link-layer address option in the message.
645 *
646 * NOTE! Linux kernel < 2.4.4 broke this rule.
647 */
648
649 /* XXX: RFC2461 7.1.1:
650 * If the IP source address is the unspecified address, the IP
651 * destination address MUST be a solicited-node multicast address.
652 */
653
654 if ((ifp = ipv6_get_ifaddr(&msg->target, dev)) != NULL) {
655 int addr_type = ipv6_addr_type(saddr);
656
657 if (ifp->flags & IFA_F_TENTATIVE) {
658 /* Address is tentative. If the source
659 is unspecified address, it is someone
660 does DAD, otherwise we ignore solicitations
661 until DAD timer expires.
662 */
663 if (addr_type == IPV6_ADDR_ANY) {
664 if (dev->type == ARPHRD_IEEE802_TR) {
665 unsigned char *sadr = skb->mac.raw ;
666 if (((sadr[8] &0x7f) != (dev->dev_addr[0] & 0x7f)) ||
667 (sadr[9] != dev->dev_addr[1]) ||
668 (sadr[10] != dev->dev_addr[2]) ||
669 (sadr[11] != dev->dev_addr[3]) ||
670 (sadr[12] != dev->dev_addr[4]) ||
671 (sadr[13] != dev->dev_addr[5]))
672 {
673 addrconf_dad_failure(ifp) ;
674 }
675 } else {
676 addrconf_dad_failure(ifp);
677 }
678 } else
679 in6_ifa_put(ifp);
680 return;
681 }
682
683 if (addr_type == IPV6_ADDR_ANY) {
684 struct in6_addr maddr;
685
686 ipv6_addr_all_nodes(&maddr);
687 ndisc_send_na(dev, NULL, &maddr, &ifp->addr,
688 ifp->idev->cnf.forwarding, 0,
689 ipv6_addr_type(&ifp->addr)&IPV6_ADDR_ANYCAST ? 0 : 1,
690 1);
691 in6_ifa_put(ifp);
692 return;
693 }
694
695 if (addr_type & IPV6_ADDR_UNICAST) {
696 int inc = ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST;
697
698 if (inc)
699 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_mcast);
700 else
701 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_ucast);
702
703 /*
704 * update / create cache entry
705 * for the source adddress
706 */
707
708 neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, dev);
709
710 if (neigh || !dev->hard_header) {
711 ndisc_send_na(dev, neigh, saddr, &ifp->addr,
712 ifp->idev->cnf.forwarding, 1,
713 ipv6_addr_type(&ifp->addr)&IPV6_ADDR_ANYCAST ? 0 : 1,
714 1);
715 if (neigh)
716 neigh_release(neigh);
717 }
718 }
719 in6_ifa_put(ifp);
720 } else if (ipv6_chk_acast_addr(dev, &msg->target)) {
721 struct inet6_dev *idev = in6_dev_get(dev);
722 int addr_type = ipv6_addr_type(saddr);
723
724 /* anycast */
725
726 if (!idev) {
727 /* XXX: count this drop? */
728 return;
729 }
730
731 if (addr_type == IPV6_ADDR_ANY) {
732 struct in6_addr maddr;
733
734 ipv6_addr_all_nodes(&maddr);
735 ndisc_send_na(dev, NULL, &maddr, &msg->target,
736 idev->cnf.forwarding, 0, 0, 1);
737 in6_dev_put(idev);
738 return;
739 }
740
741 if (addr_type & IPV6_ADDR_UNICAST) {
742 int inc = ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST;
743 if (inc)
744 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_mcast);
745 else
746 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_ucast);
747
748 /*
749 * update / create cache entry
750 * for the source adddress
751 */
752
753 neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, skb->dev);
754
755 if (neigh || !dev->hard_header) {
756 ndisc_send_na(dev, neigh, saddr,
757 &msg->target,
758 idev->cnf.forwarding, 1, 0, inc);
759 if (neigh)
760 neigh_release(neigh);
761 }
762 }
763 in6_dev_put(idev);
764 } else {
765 struct inet6_dev *in6_dev = in6_dev_get(dev);
766 int addr_type = ipv6_addr_type(saddr);
767
768 if (in6_dev && in6_dev->cnf.forwarding &&
769 (addr_type & IPV6_ADDR_UNICAST) &&
770 pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) {
771 int inc = ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST;
772
773 if (skb->stamp.tv_sec == 0 ||
774 skb->pkt_type == PACKET_HOST ||
775 inc == 0 ||
776 in6_dev->nd_parms->proxy_delay == 0) {
777 if (inc)
778 NEIGH_CACHE_STAT_INC(&nd_tbl,
779 rcv_probes_mcast);
780 else
781 NEIGH_CACHE_STAT_INC(&nd_tbl,
782 rcv_probes_ucast);
783
784 neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, dev);
785
786 if (neigh) {
787 ndisc_send_na(dev, neigh, saddr, &msg->target,
788 0, 1, 0, 1);
789 neigh_release(neigh);
790 }
791 } else {
792 struct sk_buff *n = skb_clone(skb, GFP_ATOMIC);
793 if (n)
794 pneigh_enqueue(&nd_tbl, in6_dev->nd_parms, n);
795 in6_dev_put(in6_dev);
796 return;
797 }
798 }
799 if (in6_dev)
800 in6_dev_put(in6_dev);
801 }
802 return;
803 }
804
ndisc_recv_na(struct sk_buff * skb)805 void ndisc_recv_na(struct sk_buff *skb)
806 {
807 struct nd_msg *msg = (struct nd_msg *)skb->h.raw;
808 struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
809 struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
810 u8 *lladdr = NULL;
811 int lladdrlen = 0;
812 u32 ndoptlen = skb->tail - msg->opt;
813 struct ndisc_options ndopts;
814 struct net_device *dev = skb->dev;
815 struct inet6_ifaddr *ifp;
816 struct neighbour *neigh;
817
818 if (skb->len < sizeof(struct nd_msg)) {
819 if (net_ratelimit())
820 printk(KERN_WARNING "ICMP NA: packet too short\n");
821 return;
822 }
823
824 if (ipv6_addr_type(&msg->target)&IPV6_ADDR_MULTICAST) {
825 if (net_ratelimit())
826 printk(KERN_WARNING "NDISC NA: target address is multicast\n");
827 return;
828 }
829
830 if ((ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST) &&
831 msg->icmph.icmp6_solicited) {
832 ND_PRINTK0("NDISC: solicited NA is multicasted\n");
833 return;
834 }
835
836 if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
837 if (net_ratelimit())
838 printk(KERN_WARNING "ICMP NS: invalid ND option, ignored.\n");
839 return;
840 }
841 if (ndopts.nd_opts_tgt_lladdr) {
842 lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1);
843 lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
844 if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len)) {
845 if (net_ratelimit())
846 printk(KERN_WARNING "NDISC NA: invalid lladdr length.\n");
847 return;
848 }
849 }
850 if ((ifp = ipv6_get_ifaddr(&msg->target, dev))) {
851 if (ifp->flags & IFA_F_TENTATIVE) {
852 addrconf_dad_failure(ifp);
853 return;
854 }
855 /* What should we make now? The advertisement
856 is invalid, but ndisc specs say nothing
857 about it. It could be misconfiguration, or
858 an smart proxy agent tries to help us :-)
859 */
860 ND_PRINTK0("%s: someone advertises our address!\n",
861 ifp->idev->dev->name);
862 in6_ifa_put(ifp);
863 return;
864 }
865 neigh = neigh_lookup(&nd_tbl, &msg->target, dev);
866
867 if (neigh) {
868 if (neigh->flags & NTF_ROUTER) {
869 if (msg->icmph.icmp6_router == 0) {
870 /*
871 * Change: router to host
872 */
873 struct rt6_info *rt;
874 rt = rt6_get_dflt_router(saddr, dev);
875 if (rt) {
876 /* It is safe only because
877 we aer in BH */
878 dst_release(&rt->u.dst);
879 ip6_del_rt(rt, NULL, NULL);
880 }
881 }
882 } else {
883 if (msg->icmph.icmp6_router)
884 neigh->flags |= NTF_ROUTER;
885 }
886
887 neigh_update(neigh, lladdr,
888 msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
889 msg->icmph.icmp6_override, 1);
890 neigh_release(neigh);
891 }
892 }
893
ndisc_router_discovery(struct sk_buff * skb)894 static void ndisc_router_discovery(struct sk_buff *skb)
895 {
896 struct ra_msg *ra_msg = (struct ra_msg *) skb->h.raw;
897 struct neighbour *neigh;
898 struct inet6_dev *in6_dev;
899 struct rt6_info *rt;
900 int lifetime;
901 struct ndisc_options ndopts;
902 int optlen;
903
904 __u8 * opt = (__u8 *)(ra_msg + 1);
905
906 optlen = (skb->tail - skb->h.raw) - sizeof(struct ra_msg);
907
908 if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
909 if (net_ratelimit())
910 printk(KERN_WARNING "ICMP RA: source address is not linklocal\n");
911 return;
912 }
913 if (optlen < 0) {
914 if (net_ratelimit())
915 printk(KERN_WARNING "ICMP RA: packet too short\n");
916 return;
917 }
918
919 /*
920 * set the RA_RECV flag in the interface
921 */
922
923 in6_dev = in6_dev_get(skb->dev);
924 if (in6_dev == NULL) {
925 ND_PRINTK1("RA: can't find in6 device\n");
926 return;
927 }
928 if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) {
929 in6_dev_put(in6_dev);
930 return;
931 }
932
933 if (!ndisc_parse_options(opt, optlen, &ndopts)) {
934 in6_dev_put(in6_dev);
935 if (net_ratelimit())
936 ND_PRINTK2(KERN_WARNING
937 "ICMP6 RA: invalid ND option, ignored.\n");
938 return;
939 }
940
941 if (in6_dev->if_flags & IF_RS_SENT) {
942 /*
943 * flag that an RA was received after an RS was sent
944 * out on this interface.
945 */
946 in6_dev->if_flags |= IF_RA_RCVD;
947 }
948
949 /*
950 * Remember the managed/otherconf flags from most recently
951 * received RA message (RFC 2462) -- yoshfuji
952 */
953 in6_dev->if_flags = (in6_dev->if_flags & ~(IF_RA_MANAGED |
954 IF_RA_OTHERCONF)) |
955 (ra_msg->icmph.icmp6_addrconf_managed ?
956 IF_RA_MANAGED : 0) |
957 (ra_msg->icmph.icmp6_addrconf_other ?
958 IF_RA_OTHERCONF : 0);
959
960 lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
961
962 rt = rt6_get_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
963
964 if (rt && lifetime == 0) {
965 ip6_del_rt(rt, NULL, NULL);
966 rt = NULL;
967 }
968
969 if (rt == NULL && lifetime) {
970 ND_PRINTK2("ndisc_rdisc: adding default router\n");
971
972 rt = rt6_add_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
973 if (rt == NULL) {
974 ND_PRINTK1("route_add failed\n");
975 in6_dev_put(in6_dev);
976 return;
977 }
978
979 neigh = rt->rt6i_nexthop;
980 if (neigh == NULL) {
981 ND_PRINTK1("nd: add default router: null neighbour\n");
982 dst_release(&rt->u.dst);
983 in6_dev_put(in6_dev);
984 return;
985 }
986 neigh->flags |= NTF_ROUTER;
987
988 /*
989 * If we where using an "all destinations on link" route
990 * delete it
991 */
992
993 rt6_purge_dflt_routers(RTF_ALLONLINK);
994 }
995
996 if (rt)
997 rt->rt6i_expires = jiffies + (HZ * lifetime);
998
999 if (ra_msg->icmph.icmp6_hop_limit)
1000 in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
1001
1002 /*
1003 * Update Reachable Time and Retrans Timer
1004 */
1005
1006 if (in6_dev->nd_parms) {
1007 unsigned long rtime = ntohl(ra_msg->retrans_timer);
1008
1009 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/HZ) {
1010 rtime = (rtime*HZ)/1000;
1011 if (rtime < HZ/10)
1012 rtime = HZ/10;
1013 in6_dev->nd_parms->retrans_time = rtime;
1014 }
1015
1016 rtime = ntohl(ra_msg->reachable_time);
1017 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/(3*HZ)) {
1018 rtime = (rtime*HZ)/1000;
1019
1020 if (rtime < HZ/10)
1021 rtime = HZ/10;
1022
1023 if (rtime != in6_dev->nd_parms->base_reachable_time) {
1024 in6_dev->nd_parms->base_reachable_time = rtime;
1025 in6_dev->nd_parms->gc_staletime = 3 * rtime;
1026 in6_dev->nd_parms->reachable_time = neigh_rand_reach_time(rtime);
1027 }
1028 }
1029 }
1030
1031 /*
1032 * Process options.
1033 */
1034
1035 if (rt && (neigh = rt->rt6i_nexthop) != NULL) {
1036 u8 *lladdr = NULL;
1037 int lladdrlen;
1038 if (ndopts.nd_opts_src_lladdr) {
1039 lladdr = (u8*)((ndopts.nd_opts_src_lladdr)+1);
1040 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
1041 if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) {
1042 if (net_ratelimit())
1043 ND_PRINTK2(KERN_WARNING
1044 "ICMP6 RA: Invalid lladdr length.\n");
1045 goto out;
1046 }
1047 }
1048 neigh_update(neigh, lladdr, NUD_STALE, 1, 1);
1049 }
1050
1051 if (ndopts.nd_opts_pi) {
1052 struct nd_opt_hdr *p;
1053 for (p = ndopts.nd_opts_pi;
1054 p;
1055 p = ndisc_next_option(p, ndopts.nd_opts_pi_end)) {
1056 addrconf_prefix_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3);
1057 }
1058 }
1059
1060 if (ndopts.nd_opts_mtu) {
1061 u32 mtu;
1062
1063 memcpy(&mtu, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
1064 mtu = ntohl(mtu);
1065
1066 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
1067 if (net_ratelimit()) {
1068 ND_PRINTK0("NDISC: router announcement with mtu = %d\n",
1069 mtu);
1070 }
1071 }
1072
1073 if (in6_dev->cnf.mtu6 != mtu) {
1074 in6_dev->cnf.mtu6 = mtu;
1075
1076 if (rt)
1077 rt->u.dst.pmtu = mtu;
1078
1079 rt6_mtu_change(skb->dev, mtu);
1080 }
1081 }
1082
1083 if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) {
1084 if (net_ratelimit())
1085 ND_PRINTK0(KERN_WARNING
1086 "ICMP6 RA: got illegal option with RA");
1087 }
1088 out:
1089 if (rt)
1090 dst_release(&rt->u.dst);
1091 in6_dev_put(in6_dev);
1092 }
1093
ndisc_redirect_rcv(struct sk_buff * skb)1094 static void ndisc_redirect_rcv(struct sk_buff *skb)
1095 {
1096 struct inet6_dev *in6_dev;
1097 struct icmp6hdr *icmph;
1098 struct in6_addr *dest;
1099 struct in6_addr *target; /* new first hop to destination */
1100 struct neighbour *neigh;
1101 int on_link = 0;
1102 struct ndisc_options ndopts;
1103 int optlen;
1104 u8 *lladdr = NULL;
1105 int lladdrlen;
1106
1107 if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
1108 if (net_ratelimit())
1109 printk(KERN_WARNING "ICMP redirect: source address is not linklocal\n");
1110 return;
1111 }
1112
1113 optlen = skb->tail - skb->h.raw;
1114 optlen -= sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1115
1116 if (optlen < 0) {
1117 if (net_ratelimit())
1118 printk(KERN_WARNING "ICMP redirect: packet too small\n");
1119 return;
1120 }
1121
1122 icmph = (struct icmp6hdr *) skb->h.raw;
1123 target = (struct in6_addr *) (icmph + 1);
1124 dest = target + 1;
1125
1126 if (ipv6_addr_type(dest) & IPV6_ADDR_MULTICAST) {
1127 if (net_ratelimit())
1128 printk(KERN_WARNING "ICMP redirect for multicast addr\n");
1129 return;
1130 }
1131
1132 if (ipv6_addr_cmp(dest, target) == 0) {
1133 on_link = 1;
1134 } else if (!(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) {
1135 if (net_ratelimit())
1136 printk(KERN_WARNING "ICMP redirect: target address is not linklocal\n");
1137 return;
1138 }
1139
1140 in6_dev = in6_dev_get(skb->dev);
1141 if (!in6_dev)
1142 return;
1143 if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects) {
1144 in6_dev_put(in6_dev);
1145 return;
1146 }
1147
1148 /* XXX: RFC2461 8.1:
1149 * The IP source address of the Redirect MUST be the same as the current
1150 * first-hop router for the specified ICMP Destination Address.
1151 */
1152
1153 if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) {
1154 if (net_ratelimit())
1155 ND_PRINTK2(KERN_WARNING
1156 "ICMP6 Redirect: invalid ND options, rejected.\n");
1157 in6_dev_put(in6_dev);
1158 return;
1159 }
1160 if (ndopts.nd_opts_tgt_lladdr) {
1161 lladdr = (u8*)(ndopts.nd_opts_tgt_lladdr + 1);
1162 lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
1163 if (lladdrlen != NDISC_OPT_SPACE(skb->dev->addr_len)) {
1164 if (net_ratelimit())
1165 ND_PRINTK2(KERN_WARNING
1166 "ICMP6 Redirect: invalid lladdr length.\n");
1167 in6_dev_put(in6_dev);
1168 return;
1169 }
1170 }
1171 /* passed validation tests */
1172
1173 /*
1174 We install redirect only if nexthop state is valid.
1175 */
1176
1177 neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1);
1178 if (neigh) {
1179 neigh_update(neigh, lladdr, NUD_STALE, 1, 1);
1180 if (neigh->nud_state&NUD_VALID)
1181 rt6_redirect(dest, &skb->nh.ipv6h->saddr, neigh, on_link);
1182 else
1183 __neigh_event_send(neigh, NULL);
1184 neigh_release(neigh);
1185 }
1186 in6_dev_put(in6_dev);
1187 }
1188
ndisc_send_redirect(struct sk_buff * skb,struct neighbour * neigh,struct in6_addr * target)1189 void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1190 struct in6_addr *target)
1191 {
1192 struct sock *sk = ndisc_socket->sk;
1193 int len = sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1194 struct sk_buff *buff;
1195 struct icmp6hdr *icmph;
1196 struct in6_addr saddr_buf;
1197 struct in6_addr *addrp;
1198 struct net_device *dev;
1199 struct rt6_info *rt;
1200 u8 *opt;
1201 int rd_len;
1202 int err;
1203 int hlen;
1204
1205 dev = skb->dev;
1206 rt = rt6_lookup(&skb->nh.ipv6h->saddr, NULL, dev->ifindex, 1);
1207
1208 if (rt == NULL)
1209 return;
1210
1211 if (rt->rt6i_flags & RTF_GATEWAY) {
1212 ND_PRINTK1("ndisc_send_redirect: not a neighbour\n");
1213 dst_release(&rt->u.dst);
1214 return;
1215 }
1216 if (!xrlim_allow(&rt->u.dst, 1*HZ)) {
1217 dst_release(&rt->u.dst);
1218 return;
1219 }
1220 dst_release(&rt->u.dst);
1221
1222 if (dev->addr_len) {
1223 if (neigh->nud_state&NUD_VALID) {
1224 len += NDISC_OPT_SPACE(dev->addr_len);
1225 } else {
1226 /* If nexthop is not valid, do not redirect!
1227 We will make it later, when will be sure,
1228 that it is alive.
1229 */
1230 return;
1231 }
1232 }
1233
1234 rd_len = min_t(unsigned int,
1235 IPV6_MIN_MTU-sizeof(struct ipv6hdr)-len, skb->len + 8);
1236 rd_len &= ~0x7;
1237 len += rd_len;
1238
1239 if (ipv6_get_lladdr(dev, &saddr_buf)) {
1240 ND_PRINTK1("redirect: no link_local addr for dev\n");
1241 return;
1242 }
1243
1244 buff = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15,
1245 1, &err);
1246 if (buff == NULL) {
1247 ND_PRINTK1("ndisc_send_redirect: alloc_skb failed\n");
1248 return;
1249 }
1250
1251 hlen = 0;
1252
1253 if (ndisc_build_ll_hdr(buff, dev, &skb->nh.ipv6h->saddr, NULL, len) == 0) {
1254 kfree_skb(buff);
1255 return;
1256 }
1257
1258 ip6_nd_hdr(sk, buff, dev, &saddr_buf, &skb->nh.ipv6h->saddr,
1259 IPPROTO_ICMPV6, len);
1260
1261 icmph = (struct icmp6hdr *) skb_put(buff, len);
1262
1263 memset(icmph, 0, sizeof(struct icmp6hdr));
1264 icmph->icmp6_type = NDISC_REDIRECT;
1265
1266 /*
1267 * copy target and destination addresses
1268 */
1269
1270 addrp = (struct in6_addr *)(icmph + 1);
1271 ipv6_addr_copy(addrp, target);
1272 addrp++;
1273 ipv6_addr_copy(addrp, &skb->nh.ipv6h->daddr);
1274
1275 opt = (u8*) (addrp + 1);
1276
1277 /*
1278 * include target_address option
1279 */
1280
1281 if (dev->addr_len)
1282 opt = ndisc_fill_option(opt, ND_OPT_TARGET_LL_ADDR, neigh->ha, dev->addr_len);
1283
1284 /*
1285 * build redirect option and copy skb over to the new packet.
1286 */
1287
1288 memset(opt, 0, 8);
1289 *(opt++) = ND_OPT_REDIRECT_HDR;
1290 *(opt++) = (rd_len >> 3);
1291 opt += 6;
1292
1293 memcpy(opt, skb->nh.ipv6h, rd_len - 8);
1294
1295 icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &skb->nh.ipv6h->saddr,
1296 len, IPPROTO_ICMPV6,
1297 csum_partial((u8 *) icmph, len, 0));
1298
1299 dev_queue_xmit(buff);
1300
1301 ICMP6_INC_STATS(Icmp6OutRedirects);
1302 ICMP6_INC_STATS(Icmp6OutMsgs);
1303 }
1304
pndisc_redo(struct sk_buff * skb)1305 static void pndisc_redo(struct sk_buff *skb)
1306 {
1307 ndisc_rcv(skb);
1308 kfree_skb(skb);
1309 }
1310
ndisc_rcv(struct sk_buff * skb)1311 int ndisc_rcv(struct sk_buff *skb)
1312 {
1313 struct nd_msg *msg = (struct nd_msg *) skb->h.raw;
1314
1315 __skb_push(skb, skb->data-skb->h.raw);
1316
1317 if (skb->nh.ipv6h->hop_limit != 255) {
1318 if (net_ratelimit())
1319 printk(KERN_WARNING
1320 "ICMP NDISC: fake message with non-255 Hop Limit received: %d\n",
1321 skb->nh.ipv6h->hop_limit);
1322 return 0;
1323 }
1324
1325 if (msg->icmph.icmp6_code != 0) {
1326 if (net_ratelimit())
1327 printk(KERN_WARNING "ICMP NDISC: code is not zero\n");
1328 return 0;
1329 }
1330
1331 switch (msg->icmph.icmp6_type) {
1332 case NDISC_NEIGHBOUR_SOLICITATION:
1333 ndisc_recv_ns(skb);
1334 break;
1335
1336 case NDISC_NEIGHBOUR_ADVERTISEMENT:
1337 ndisc_recv_na(skb);
1338 break;
1339
1340 case NDISC_ROUTER_ADVERTISEMENT:
1341 ndisc_router_discovery(skb);
1342 break;
1343
1344 case NDISC_REDIRECT:
1345 ndisc_redirect_rcv(skb);
1346 break;
1347 };
1348
1349 return 0;
1350 }
1351
ndisc_netdev_event(struct notifier_block * this,unsigned long event,void * ptr)1352 static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
1353 {
1354 struct net_device *dev = ptr;
1355
1356 switch (event) {
1357 case NETDEV_CHANGEADDR:
1358 neigh_changeaddr(&nd_tbl, dev);
1359 fib6_run_gc(0);
1360 break;
1361 default:
1362 break;
1363 }
1364
1365 return NOTIFY_DONE;
1366 }
1367
1368 struct notifier_block ndisc_netdev_notifier = {
1369 .notifier_call = ndisc_netdev_event,
1370 };
1371
ndisc_init(struct net_proto_family * ops)1372 int __init ndisc_init(struct net_proto_family *ops)
1373 {
1374 struct sock *sk;
1375 int err;
1376
1377 ndisc_socket = sock_alloc();
1378 if (ndisc_socket == NULL) {
1379 printk(KERN_ERR
1380 "Failed to create the NDISC control socket.\n");
1381 return -1;
1382 }
1383 ndisc_socket->inode->i_uid = 0;
1384 ndisc_socket->inode->i_gid = 0;
1385 ndisc_socket->type = SOCK_RAW;
1386
1387 if((err = ops->create(ndisc_socket, IPPROTO_ICMPV6)) < 0) {
1388 printk(KERN_DEBUG
1389 "Failed to initialize the NDISC control socket (err %d).\n",
1390 err);
1391 sock_release(ndisc_socket);
1392 ndisc_socket = NULL; /* For safety. */
1393 return err;
1394 }
1395
1396 sk = ndisc_socket->sk;
1397 sk->allocation = GFP_ATOMIC;
1398 sk->net_pinfo.af_inet6.hop_limit = 255;
1399 /* Do not loopback ndisc messages */
1400 sk->net_pinfo.af_inet6.mc_loop = 0;
1401 sk->prot->unhash(sk);
1402
1403 /*
1404 * Initialize the neighbour table
1405 */
1406
1407 neigh_table_init(&nd_tbl);
1408
1409 #ifdef CONFIG_SYSCTL
1410 neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, NET_IPV6_NEIGH, "ipv6");
1411 #endif
1412
1413 register_netdevice_notifier(&ndisc_netdev_notifier);
1414 return 0;
1415 }
1416
ndisc_cleanup(void)1417 void ndisc_cleanup(void)
1418 {
1419 neigh_table_clear(&nd_tbl);
1420 sock_release(ndisc_socket);
1421 ndisc_socket = NULL; /* For safety. */
1422 }
1423