ndisc.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:30k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Neighbour Discovery for IPv6
  3.  * Linux INET6 implementation 
  4.  *
  5.  * Authors:
  6.  * Pedro Roque <roque@di.fc.ul.pt>
  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.  * Changes:
  16.  *
  17.  * Lars Fenneberg : fixed MTU setting on receipt
  18.  * of an RA.
  19.  *
  20.  * Janos Farkas : kmalloc failure checks
  21.  * Alexey Kuznetsov : state machine reworked
  22.  * and moved to net/core.
  23.  * Pekka Savola : RFC2461 validation
  24.  */
  25. /* Set to 3 to get tracing... */
  26. #define ND_DEBUG 1
  27. #define ND_PRINTK(x...) printk(KERN_DEBUG x)
  28. #define ND_NOPRINTK(x...) do { ; } while(0)
  29. #define ND_PRINTK0 ND_PRINTK
  30. #define ND_PRINTK1 ND_NOPRINTK
  31. #define ND_PRINTK2 ND_NOPRINTK
  32. #if ND_DEBUG >= 1
  33. #undef ND_PRINTK1
  34. #define ND_PRINTK1 ND_PRINTK
  35. #endif
  36. #if ND_DEBUG >= 2
  37. #undef ND_PRINTK2
  38. #define ND_PRINTK2 ND_PRINTK
  39. #endif
  40. #define __NO_VERSION__
  41. #include <linux/module.h>
  42. #include <linux/config.h>
  43. #include <linux/errno.h>
  44. #include <linux/types.h>
  45. #include <linux/socket.h>
  46. #include <linux/sockios.h>
  47. #include <linux/sched.h>
  48. #include <linux/net.h>
  49. #include <linux/in6.h>
  50. #include <linux/route.h>
  51. #include <linux/init.h>
  52. #ifdef CONFIG_SYSCTL
  53. #include <linux/sysctl.h>
  54. #endif
  55. #include <linux/if_arp.h>
  56. #include <linux/ipv6.h>
  57. #include <linux/icmpv6.h>
  58. #include <net/sock.h>
  59. #include <net/snmp.h>
  60. #include <net/ipv6.h>
  61. #include <net/protocol.h>
  62. #include <net/ndisc.h>
  63. #include <net/ip6_route.h>
  64. #include <net/addrconf.h>
  65. #include <net/icmp.h>
  66. #include <net/checksum.h>
  67. #include <linux/proc_fs.h>
  68. static struct socket *ndisc_socket;
  69. static u32 ndisc_hash(const void *pkey, const struct net_device *dev);
  70. static int ndisc_constructor(struct neighbour *neigh);
  71. static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb);
  72. static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb);
  73. static int pndisc_constructor(struct pneigh_entry *n);
  74. static void pndisc_destructor(struct pneigh_entry *n);
  75. static void pndisc_redo(struct sk_buff *skb);
  76. static struct neigh_ops ndisc_generic_ops =
  77. {
  78. AF_INET6,
  79. NULL,
  80. ndisc_solicit,
  81. ndisc_error_report,
  82. neigh_resolve_output,
  83. neigh_connected_output,
  84. dev_queue_xmit,
  85. dev_queue_xmit
  86. };
  87. static struct neigh_ops ndisc_hh_ops =
  88. {
  89. AF_INET6,
  90. NULL,
  91. ndisc_solicit,
  92. ndisc_error_report,
  93. neigh_resolve_output,
  94. neigh_resolve_output,
  95. dev_queue_xmit,
  96. dev_queue_xmit
  97. };
  98. static struct neigh_ops ndisc_direct_ops =
  99. {
  100. AF_INET6,
  101. NULL,
  102. NULL,
  103. NULL,
  104. dev_queue_xmit,
  105. dev_queue_xmit,
  106. dev_queue_xmit,
  107. dev_queue_xmit
  108. };
  109. struct neigh_table nd_tbl =
  110. {
  111. NULL,
  112. AF_INET6,
  113. sizeof(struct neighbour) + sizeof(struct in6_addr),
  114. sizeof(struct in6_addr),
  115. ndisc_hash,
  116. ndisc_constructor,
  117. pndisc_constructor,
  118. pndisc_destructor,
  119. pndisc_redo,
  120. "ndisc_cache",
  121.         { NULL, NULL, &nd_tbl, 0, NULL, NULL,
  122.   30*HZ, 1*HZ, 60*HZ, 30*HZ, 5*HZ, 3, 3, 0, 3, 1*HZ, (8*HZ)/10, 64, 0 },
  123. 30*HZ, 128, 512, 1024,
  124. };
  125. #define NDISC_OPT_SPACE(len) (((len)+2+7)&~7)
  126. static u8 *ndisc_fill_option(u8 *opt, int type, void *data, int data_len)
  127. {
  128. int space = NDISC_OPT_SPACE(data_len);
  129. opt[0] = type;
  130. opt[1] = space>>3;
  131. memcpy(opt+2, data, data_len);
  132. data_len += 2;
  133. opt += data_len;
  134. if ((space -= data_len) > 0)
  135. memset(opt, 0, space);
  136. return opt + space;
  137. }
  138. int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir)
  139. {
  140. switch (dev->type) {
  141. case ARPHRD_ETHER:
  142. case ARPHRD_IEEE802: /* Not sure. Check it later. --ANK */
  143. case ARPHRD_FDDI:
  144. ipv6_eth_mc_map(addr, buf);
  145. return 0;
  146. case ARPHRD_IEEE802_TR:
  147. ipv6_tr_mc_map(addr,buf);
  148. return 0;
  149. default:
  150. if (dir) {
  151. memcpy(buf, dev->broadcast, dev->addr_len);
  152. return 0;
  153. }
  154. }
  155. return -EINVAL;
  156. }
  157. static u32 ndisc_hash(const void *pkey, const struct net_device *dev)
  158. {
  159. u32 hash_val;
  160. hash_val = *(u32*)(pkey + sizeof(struct in6_addr) - 4);
  161. hash_val ^= (hash_val>>16);
  162. hash_val ^= hash_val>>8;
  163. hash_val ^= hash_val>>3;
  164. hash_val = (hash_val^dev->ifindex)&NEIGH_HASHMASK;
  165. return hash_val;
  166. }
  167. static int ndisc_constructor(struct neighbour *neigh)
  168. {
  169. struct in6_addr *addr = (struct in6_addr*)&neigh->primary_key;
  170. struct net_device *dev = neigh->dev;
  171. struct inet6_dev *in6_dev = in6_dev_get(dev);
  172. int addr_type;
  173. if (in6_dev == NULL)
  174. return -EINVAL;
  175. addr_type = ipv6_addr_type(addr);
  176. if (in6_dev->nd_parms)
  177. neigh->parms = in6_dev->nd_parms;
  178. if (addr_type&IPV6_ADDR_MULTICAST)
  179. neigh->type = RTN_MULTICAST;
  180. else
  181. neigh->type = RTN_UNICAST;
  182. if (dev->hard_header == NULL) {
  183. neigh->nud_state = NUD_NOARP;
  184. neigh->ops = &ndisc_direct_ops;
  185. neigh->output = neigh->ops->queue_xmit;
  186. } else {
  187. if (addr_type&IPV6_ADDR_MULTICAST) {
  188. neigh->nud_state = NUD_NOARP;
  189. ndisc_mc_map(addr, neigh->ha, dev, 1);
  190. } else if (dev->flags&(IFF_NOARP|IFF_LOOPBACK)) {
  191. neigh->nud_state = NUD_NOARP;
  192. memcpy(neigh->ha, dev->dev_addr, dev->addr_len);
  193. if (dev->flags&IFF_LOOPBACK)
  194. neigh->type = RTN_LOCAL;
  195. } else if (dev->flags&IFF_POINTOPOINT) {
  196. neigh->nud_state = NUD_NOARP;
  197. memcpy(neigh->ha, dev->broadcast, dev->addr_len);
  198. }
  199. if (dev->hard_header_cache)
  200. neigh->ops = &ndisc_hh_ops;
  201. else
  202. neigh->ops = &ndisc_generic_ops;
  203. if (neigh->nud_state&NUD_VALID)
  204. neigh->output = neigh->ops->connected_output;
  205. else
  206. neigh->output = neigh->ops->output;
  207. }
  208. in6_dev_put(in6_dev);
  209. return 0;
  210. }
  211. static int pndisc_constructor(struct pneigh_entry *n)
  212. {
  213. struct in6_addr *addr = (struct in6_addr*)&n->key;
  214. struct in6_addr maddr;
  215. struct net_device *dev = n->dev;
  216. if (dev == NULL || __in6_dev_get(dev) == NULL)
  217. return -EINVAL;
  218. addrconf_addr_solict_mult(addr, &maddr);
  219. ipv6_dev_mc_inc(dev, &maddr);
  220. return 0;
  221. }
  222. static void pndisc_destructor(struct pneigh_entry *n)
  223. {
  224. struct in6_addr *addr = (struct in6_addr*)&n->key;
  225. struct in6_addr maddr;
  226. struct net_device *dev = n->dev;
  227. if (dev == NULL || __in6_dev_get(dev) == NULL)
  228. return;
  229. addrconf_addr_solict_mult(addr, &maddr);
  230. ipv6_dev_mc_dec(dev, &maddr);
  231. }
  232. static int
  233. ndisc_build_ll_hdr(struct sk_buff *skb, struct net_device *dev,
  234.    struct in6_addr *daddr, struct neighbour *neigh, int len)
  235. {
  236. unsigned char ha[MAX_ADDR_LEN];
  237. unsigned char *h_dest = NULL;
  238. skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
  239. if (dev->hard_header) {
  240. if (ipv6_addr_type(daddr) & IPV6_ADDR_MULTICAST) {
  241. ndisc_mc_map(daddr, ha, dev, 1);
  242. h_dest = ha;
  243. } else if (neigh) {
  244. read_lock_bh(&neigh->lock);
  245. if (neigh->nud_state&NUD_VALID) {
  246. memcpy(ha, neigh->ha, dev->addr_len);
  247. h_dest = ha;
  248. }
  249. read_unlock_bh(&neigh->lock);
  250. } else {
  251. neigh = neigh_lookup(&nd_tbl, daddr, dev);
  252. if (neigh) {
  253. read_lock_bh(&neigh->lock);
  254. if (neigh->nud_state&NUD_VALID) {
  255. memcpy(ha, neigh->ha, dev->addr_len);
  256. h_dest = ha;
  257. }
  258. read_unlock_bh(&neigh->lock);
  259. neigh_release(neigh);
  260. }
  261. }
  262. if (dev->hard_header(skb, dev, ETH_P_IPV6, h_dest, NULL, len) < 0)
  263. return 0;
  264. }
  265. return 1;
  266. }
  267. /*
  268.  * Send a Neighbour Advertisement
  269.  */
  270. void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
  271.    struct in6_addr *daddr, struct in6_addr *solicited_addr,
  272.    int router, int solicited, int override, int inc_opt) 
  273. {
  274.         struct sock *sk = ndisc_socket->sk;
  275.         struct nd_msg *msg;
  276.         int len;
  277.         struct sk_buff *skb;
  278. int err;
  279. len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
  280. if (inc_opt) {
  281. if (dev->addr_len)
  282. len += NDISC_OPT_SPACE(dev->addr_len);
  283. else
  284. inc_opt = 0;
  285. }
  286. skb = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15,
  287.   0, &err);
  288. if (skb == NULL) {
  289. ND_PRINTK1("send_na: alloc skb failedn");
  290. return;
  291. }
  292. if (ndisc_build_ll_hdr(skb, dev, daddr, neigh, len) == 0) {
  293. kfree_skb(skb);
  294. return;
  295. }
  296. ip6_nd_hdr(sk, skb, dev, solicited_addr, daddr, IPPROTO_ICMPV6, len);
  297. msg = (struct nd_msg *) skb_put(skb, len);
  298.         msg->icmph.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
  299.         msg->icmph.icmp6_code = 0;
  300.         msg->icmph.icmp6_cksum = 0;
  301.         msg->icmph.icmp6_unused = 0;
  302.         msg->icmph.icmp6_router    = router;
  303.         msg->icmph.icmp6_solicited = solicited;
  304.         msg->icmph.icmp6_override  = !!override;
  305.         /* Set the target address. */
  306. ipv6_addr_copy(&msg->target, solicited_addr);
  307. if (inc_opt)
  308. ndisc_fill_option((void*)&msg->opt, ND_OPT_TARGET_LL_ADDR, dev->dev_addr, dev->addr_len);
  309. /* checksum */
  310. msg->icmph.icmp6_cksum = csum_ipv6_magic(solicited_addr, daddr, len, 
  311.  IPPROTO_ICMPV6,
  312.  csum_partial((__u8 *) msg, 
  313.       len, 0));
  314. dev_queue_xmit(skb);
  315. ICMP6_INC_STATS(Icmp6OutNeighborAdvertisements);
  316. ICMP6_INC_STATS(Icmp6OutMsgs);
  317. }        
  318. void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
  319.    struct in6_addr *solicit,
  320.    struct in6_addr *daddr, struct in6_addr *saddr) 
  321. {
  322.         struct sock *sk = ndisc_socket->sk;
  323.         struct sk_buff *skb;
  324.         struct nd_msg *msg;
  325. struct in6_addr addr_buf;
  326.         int len;
  327. int err;
  328. int send_llinfo;
  329. if (saddr == NULL) {
  330. if (ipv6_get_lladdr(dev, &addr_buf))
  331. return;
  332. saddr = &addr_buf;
  333. }
  334. len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
  335. send_llinfo = dev->addr_len && ipv6_addr_type(saddr) != IPV6_ADDR_ANY;
  336. if (send_llinfo)
  337. len += NDISC_OPT_SPACE(dev->addr_len);
  338. skb = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15,
  339.   0, &err);
  340. if (skb == NULL) {
  341. ND_PRINTK1("send_ns: alloc skb failedn");
  342. return;
  343. }
  344. if (ndisc_build_ll_hdr(skb, dev, daddr, neigh, len) == 0) {
  345. kfree_skb(skb);
  346. return;
  347. }
  348. ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
  349. msg = (struct nd_msg *)skb_put(skb, len);
  350. msg->icmph.icmp6_type = NDISC_NEIGHBOUR_SOLICITATION;
  351. msg->icmph.icmp6_code = 0;
  352. msg->icmph.icmp6_cksum = 0;
  353. msg->icmph.icmp6_unused = 0;
  354. /* Set the target address. */
  355. ipv6_addr_copy(&msg->target, solicit);
  356. if (send_llinfo)
  357. ndisc_fill_option((void*)&msg->opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr, dev->addr_len);
  358. /* checksum */
  359. msg->icmph.icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr,
  360.  daddr, len, 
  361.  IPPROTO_ICMPV6,
  362.  csum_partial((__u8 *) msg, 
  363.       len, 0));
  364. /* send it! */
  365. dev_queue_xmit(skb);
  366. ICMP6_INC_STATS(Icmp6OutNeighborSolicits);
  367. ICMP6_INC_STATS(Icmp6OutMsgs);
  368. }
  369. void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
  370.    struct in6_addr *daddr)
  371. {
  372. struct sock *sk = ndisc_socket->sk;
  373.         struct sk_buff *skb;
  374.         struct icmp6hdr *hdr;
  375. __u8 * opt;
  376.         int len;
  377. int err;
  378. len = sizeof(struct icmp6hdr);
  379. if (dev->addr_len)
  380. len += NDISC_OPT_SPACE(dev->addr_len);
  381.         skb = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15,
  382.   0, &err);
  383. if (skb == NULL) {
  384. ND_PRINTK1("send_ns: alloc skb failedn");
  385. return;
  386. }
  387. if (ndisc_build_ll_hdr(skb, dev, daddr, NULL, len) == 0) {
  388. kfree_skb(skb);
  389. return;
  390. }
  391. ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
  392.         hdr = (struct icmp6hdr *) skb_put(skb, len);
  393.         hdr->icmp6_type = NDISC_ROUTER_SOLICITATION;
  394.         hdr->icmp6_code = 0;
  395.         hdr->icmp6_cksum = 0;
  396.         hdr->icmp6_unused = 0;
  397. opt = (u8*) (hdr + 1);
  398. if (dev->addr_len)
  399. ndisc_fill_option(opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr, dev->addr_len);
  400. /* checksum */
  401. hdr->icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr, daddr, len,
  402.    IPPROTO_ICMPV6,
  403.    csum_partial((__u8 *) hdr, len, 0));
  404. /* send it! */
  405. dev_queue_xmit(skb);
  406. ICMP6_INC_STATS(Icmp6OutRouterSolicits);
  407. ICMP6_INC_STATS(Icmp6OutMsgs);
  408. }
  409.    
  410. static u8 * ndisc_find_option(u8 *opt, int opt_len, int len, int option)
  411. {
  412. while (opt_len <= len) {
  413. int l = opt[1]<<3;
  414. if (opt[0] == option && l >= opt_len)
  415. return opt + 2;
  416. if (l == 0) {
  417. if (net_ratelimit())
  418.     printk(KERN_WARNING "ndisc: option has 0 lenn");
  419. return NULL;
  420. }
  421. opt += l;
  422. len -= l;
  423. }
  424. return NULL;
  425. }
  426. static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb)
  427. {
  428. /*
  429.  * "The sender MUST return an ICMP
  430.  *  destination unreachable"
  431.  */
  432. dst_link_failure(skb);
  433. kfree_skb(skb);
  434. }
  435. /* Called with locked neigh: either read or both */
  436. static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
  437. {
  438. struct in6_addr *saddr = NULL;
  439. struct in6_addr mcaddr;
  440. struct net_device *dev = neigh->dev;
  441. struct in6_addr *target = (struct in6_addr *)&neigh->primary_key;
  442. int probes = atomic_read(&neigh->probes);
  443. if (skb && ipv6_chk_addr(&skb->nh.ipv6h->saddr, dev))
  444. saddr = &skb->nh.ipv6h->saddr;
  445. if ((probes -= neigh->parms->ucast_probes) < 0) {
  446. if (!(neigh->nud_state&NUD_VALID))
  447. ND_PRINTK1("trying to ucast probe in NUD_INVALIDn");
  448. ndisc_send_ns(dev, neigh, target, target, saddr);
  449. } else if ((probes -= neigh->parms->app_probes) < 0) {
  450. #ifdef CONFIG_ARPD
  451. neigh_app_ns(neigh);
  452. #endif
  453. } else {
  454. addrconf_addr_solict_mult(target, &mcaddr);
  455. ndisc_send_ns(dev, NULL, target, &mcaddr, saddr);
  456. }
  457. }
  458. static void ndisc_update(struct neighbour *neigh, u8* opt, int len, int type)
  459. {
  460. opt = ndisc_find_option(opt, neigh->dev->addr_len+2, len, type);
  461. neigh_update(neigh, opt, NUD_STALE, 1, 1);
  462. }
  463. static void ndisc_router_discovery(struct sk_buff *skb)
  464. {
  465.         struct ra_msg *ra_msg = (struct ra_msg *) skb->h.raw;
  466. struct neighbour *neigh;
  467. struct inet6_dev *in6_dev;
  468. struct rt6_info *rt;
  469. int lifetime;
  470. int optlen;
  471. __u8 * opt = (__u8 *)(ra_msg + 1);
  472. optlen = (skb->tail - skb->h.raw) - sizeof(struct ra_msg);
  473. if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
  474. if (net_ratelimit())
  475. printk(KERN_WARNING "ICMP RA: source address is not linklocaln");
  476. return;
  477. }
  478. /*
  479.  * set the RA_RECV flag in the interface
  480.  */
  481. in6_dev = in6_dev_get(skb->dev);
  482. if (in6_dev == NULL) {
  483. ND_PRINTK1("RA: can't find in6 devicen");
  484. return;
  485. }
  486. if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) {
  487. in6_dev_put(in6_dev);
  488. return;
  489. }
  490. if (in6_dev->if_flags & IF_RS_SENT) {
  491. /*
  492.  * flag that an RA was received after an RS was sent
  493.  * out on this interface.
  494.  */
  495. in6_dev->if_flags |= IF_RA_RCVD;
  496. }
  497. lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
  498. rt = rt6_get_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
  499. if (rt && lifetime == 0) {
  500. ip6_del_rt(rt);
  501. rt = NULL;
  502. }
  503. if (rt == NULL && lifetime) {
  504. ND_PRINTK2("ndisc_rdisc: adding default routern");
  505. rt = rt6_add_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
  506. if (rt == NULL) {
  507. ND_PRINTK1("route_add failedn");
  508. in6_dev_put(in6_dev);
  509. return;
  510. }
  511. neigh = rt->rt6i_nexthop;
  512. if (neigh == NULL) {
  513. ND_PRINTK1("nd: add default router: null neighbourn");
  514. dst_release(&rt->u.dst);
  515. in6_dev_put(in6_dev);
  516. return;
  517. }
  518. neigh->flags |= NTF_ROUTER;
  519. /*
  520.  * If we where using an "all destinations on link" route
  521.  * delete it
  522.  */
  523. rt6_purge_dflt_routers(RTF_ALLONLINK);
  524. }
  525. if (rt)
  526. rt->rt6i_expires = jiffies + (HZ * lifetime);
  527. if (ra_msg->icmph.icmp6_hop_limit)
  528. in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
  529. /*
  530.  * Update Reachable Time and Retrans Timer
  531.  */
  532. if (in6_dev->nd_parms) {
  533. __u32 rtime = ntohl(ra_msg->retrans_timer);
  534. if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/HZ) {
  535. rtime = (rtime*HZ)/1000;
  536. if (rtime < HZ/10)
  537. rtime = HZ/10;
  538. in6_dev->nd_parms->retrans_time = rtime;
  539. }
  540. rtime = ntohl(ra_msg->reachable_time);
  541. if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/(3*HZ)) {
  542. rtime = (rtime*HZ)/1000;
  543. if (rtime < HZ/10)
  544. rtime = HZ/10;
  545. if (rtime != in6_dev->nd_parms->base_reachable_time) {
  546. in6_dev->nd_parms->base_reachable_time = rtime;
  547. in6_dev->nd_parms->gc_staletime = 3 * rtime;
  548. in6_dev->nd_parms->reachable_time = neigh_rand_reach_time(rtime);
  549. }
  550. }
  551. }
  552. /*
  553.  * Process options.
  554.  */
  555.         while (optlen > 0) {
  556.                 int len = (opt[1] << 3);
  557. if (len == 0) {
  558. ND_PRINTK0("RA: opt has 0 lenn");
  559. break;
  560. }
  561.                 switch(*opt) {
  562.                 case ND_OPT_SOURCE_LL_ADDR:
  563. if (rt == NULL)
  564. break;
  565. if ((neigh = rt->rt6i_nexthop) != NULL &&
  566.     skb->dev->addr_len + 2 >= len)
  567. neigh_update(neigh, opt+2, NUD_STALE, 1, 1);
  568. break;
  569.                 case ND_OPT_PREFIX_INFO:
  570. addrconf_prefix_rcv(skb->dev, opt, len);
  571.                         break;
  572.                 case ND_OPT_MTU:
  573. {
  574. int mtu;
  575. mtu = htonl(*(__u32 *)(opt+4));
  576. if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
  577. ND_PRINTK0("NDISC: router "
  578.    "announcement with mtu = %dn",
  579.    mtu);
  580. break;
  581. }
  582. if (in6_dev->cnf.mtu6 != mtu) {
  583. in6_dev->cnf.mtu6 = mtu;
  584. if (rt)
  585. rt->u.dst.pmtu = mtu;
  586. rt6_mtu_change(skb->dev, mtu);
  587. }
  588. }
  589.                         break;
  590. case ND_OPT_TARGET_LL_ADDR:
  591. case ND_OPT_REDIRECT_HDR:
  592. ND_PRINTK0("got illegal option with RA");
  593. break;
  594. default:
  595. ND_PRINTK0("unkown option in RAn");
  596.                 };
  597.                 optlen -= len;
  598.                 opt += len;
  599.         }
  600. if (rt)
  601. dst_release(&rt->u.dst);
  602. in6_dev_put(in6_dev);
  603. }
  604. static void ndisc_redirect_rcv(struct sk_buff *skb)
  605. {
  606. struct inet6_dev *in6_dev;
  607. struct icmp6hdr *icmph;
  608. struct in6_addr *dest;
  609. struct in6_addr *target; /* new first hop to destination */
  610. struct neighbour *neigh;
  611. int on_link = 0;
  612. int optlen;
  613. if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
  614. if (net_ratelimit())
  615. printk(KERN_WARNING "ICMP redirect: source address is not linklocaln");
  616. return;
  617. }
  618. optlen = skb->tail - skb->h.raw;
  619. optlen -= sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
  620. if (optlen < 0) {
  621. if (net_ratelimit())
  622. printk(KERN_WARNING "ICMP redirect: packet too smalln");
  623. return;
  624. }
  625. icmph = (struct icmp6hdr *) skb->h.raw;
  626. target = (struct in6_addr *) (icmph + 1);
  627. dest = target + 1;
  628. if (ipv6_addr_type(dest) & IPV6_ADDR_MULTICAST) {
  629. if (net_ratelimit())
  630. printk(KERN_WARNING "ICMP redirect for multicast addrn");
  631. return;
  632. }
  633. if (ipv6_addr_cmp(dest, target) == 0) {
  634. on_link = 1;
  635. } else if (!(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) {
  636. if (net_ratelimit())
  637. printk(KERN_WARNING "ICMP redirect: target address is not linklocaln");
  638. return;
  639. }
  640. in6_dev = in6_dev_get(skb->dev);
  641. if (!in6_dev)
  642. return;
  643. if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects) {
  644. in6_dev_put(in6_dev);
  645. return;
  646. }
  647. /* XXX: RFC2461 8.1: 
  648.  * The IP source address of the Redirect MUST be the same as the current
  649.  * first-hop router for the specified ICMP Destination Address.
  650.  */
  651. /* passed validation tests */
  652. /*
  653.    We install redirect only if nexthop state is valid.
  654.  */
  655. neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1);
  656. if (neigh) {
  657. ndisc_update(neigh, (u8*)(dest + 1), optlen, ND_OPT_TARGET_LL_ADDR);
  658. if (neigh->nud_state&NUD_VALID)
  659. rt6_redirect(dest, &skb->nh.ipv6h->saddr, neigh, on_link);
  660. else
  661. __neigh_event_send(neigh, NULL);
  662. neigh_release(neigh);
  663. }
  664. in6_dev_put(in6_dev);
  665. }
  666. void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
  667.  struct in6_addr *target)
  668. {
  669. struct sock *sk = ndisc_socket->sk;
  670. int len = sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
  671. struct sk_buff *buff;
  672. struct icmp6hdr *icmph;
  673. struct in6_addr saddr_buf;
  674. struct in6_addr *addrp;
  675. struct net_device *dev;
  676. struct rt6_info *rt;
  677. u8 *opt;
  678. int rd_len;
  679. int err;
  680. int hlen;
  681. dev = skb->dev;
  682. rt = rt6_lookup(&skb->nh.ipv6h->saddr, NULL, dev->ifindex, 1);
  683. if (rt == NULL)
  684. return;
  685. if (rt->rt6i_flags & RTF_GATEWAY) {
  686. ND_PRINTK1("ndisc_send_redirect: not a neighbourn");
  687. dst_release(&rt->u.dst);
  688. return;
  689. }
  690. if (!xrlim_allow(&rt->u.dst, 1*HZ)) {
  691. dst_release(&rt->u.dst);
  692. return;
  693. }
  694. dst_release(&rt->u.dst);
  695. if (dev->addr_len) {
  696. if (neigh->nud_state&NUD_VALID) {
  697. len  += NDISC_OPT_SPACE(dev->addr_len);
  698. } else {
  699. /* If nexthop is not valid, do not redirect!
  700.    We will make it later, when will be sure,
  701.    that it is alive.
  702.  */
  703. return;
  704. }
  705. }
  706. rd_len = min_t(unsigned int,
  707.      IPV6_MIN_MTU-sizeof(struct ipv6hdr)-len, skb->len + 8);
  708. rd_len &= ~0x7;
  709. len += rd_len;
  710. if (ipv6_get_lladdr(dev, &saddr_buf)) {
  711.   ND_PRINTK1("redirect: no link_local addr for devn");
  712.   return;
  713.   }
  714. buff = sock_alloc_send_skb(sk, MAX_HEADER + len + dev->hard_header_len + 15,
  715.    0, &err);
  716. if (buff == NULL) {
  717. ND_PRINTK1("ndisc_send_redirect: alloc_skb failedn");
  718. return;
  719. }
  720. hlen = 0;
  721. if (ndisc_build_ll_hdr(buff, dev, &skb->nh.ipv6h->saddr, NULL, len) == 0) {
  722. kfree_skb(buff);
  723. return;
  724. }
  725. ip6_nd_hdr(sk, buff, dev, &saddr_buf, &skb->nh.ipv6h->saddr,
  726.    IPPROTO_ICMPV6, len);
  727. icmph = (struct icmp6hdr *) skb_put(buff, len);
  728. memset(icmph, 0, sizeof(struct icmp6hdr));
  729. icmph->icmp6_type = NDISC_REDIRECT;
  730. /*
  731.  * copy target and destination addresses
  732.  */
  733. addrp = (struct in6_addr *)(icmph + 1);
  734. ipv6_addr_copy(addrp, target);
  735. addrp++;
  736. ipv6_addr_copy(addrp, &skb->nh.ipv6h->daddr);
  737. opt = (u8*) (addrp + 1);
  738. /*
  739.  * include target_address option
  740.  */
  741. if (dev->addr_len)
  742. opt = ndisc_fill_option(opt, ND_OPT_TARGET_LL_ADDR, neigh->ha, dev->addr_len);
  743. /*
  744.  * build redirect option and copy skb over to the new packet.
  745.  */
  746. memset(opt, 0, 8);
  747. *(opt++) = ND_OPT_REDIRECT_HDR;
  748. *(opt++) = (rd_len >> 3);
  749. opt += 6;
  750. memcpy(opt, skb->nh.ipv6h, rd_len - 8);
  751. icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &skb->nh.ipv6h->saddr,
  752.      len, IPPROTO_ICMPV6,
  753.      csum_partial((u8 *) icmph, len, 0));
  754. dev_queue_xmit(buff);
  755. ICMP6_INC_STATS(Icmp6OutRedirects);
  756. ICMP6_INC_STATS(Icmp6OutMsgs);
  757. }
  758. static __inline__ struct neighbour *
  759. ndisc_recv_ns(struct in6_addr *saddr, struct sk_buff *skb)
  760. {
  761. u8 *opt;
  762. opt = skb->h.raw;
  763. opt += sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
  764. opt = ndisc_find_option(opt, skb->dev->addr_len+2, skb->tail - opt, ND_OPT_SOURCE_LL_ADDR);
  765. return neigh_event_ns(&nd_tbl, opt, saddr, skb->dev);
  766. }
  767. static __inline__ int ndisc_recv_na(struct neighbour *neigh, struct sk_buff *skb)
  768. {
  769. struct nd_msg *msg = (struct nd_msg *) skb->h.raw;
  770. u8 *opt;
  771. opt = skb->h.raw;
  772. opt += sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
  773. opt = ndisc_find_option(opt, skb->dev->addr_len+2, skb->tail - opt, ND_OPT_TARGET_LL_ADDR);
  774. return neigh_update(neigh, opt,
  775.     msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
  776.     msg->icmph.icmp6_override, 1);
  777. }
  778. static void pndisc_redo(struct sk_buff *skb)
  779. {
  780. ndisc_rcv(skb);
  781. kfree_skb(skb);
  782. }
  783. int ndisc_rcv(struct sk_buff *skb)
  784. {
  785. struct net_device *dev = skb->dev;
  786. struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
  787. struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
  788. struct nd_msg *msg = (struct nd_msg *) skb->h.raw;
  789. struct neighbour *neigh;
  790. struct inet6_ifaddr *ifp;
  791. unsigned int payload_len;
  792. __skb_push(skb, skb->data-skb->h.raw);
  793. if (skb->nh.ipv6h->hop_limit != 255) {
  794. if (net_ratelimit())
  795. printk(KERN_WARNING
  796.        "ICMP NDISC: fake message with non-255 Hop Limit received: %dn",
  797.         skb->nh.ipv6h->hop_limit);
  798. return 0;
  799. }
  800. if (msg->icmph.icmp6_code != 0) {
  801. if (net_ratelimit())
  802. printk(KERN_WARNING "ICMP NDISC: code is not zeron");
  803. return 0;
  804. }
  805. /* XXX: RFC2461 Validation of [all ndisc messages]:
  806.  * All included ndisc options MUST be of non-zero length
  807.  * (Some checking in ndisc_find_option)
  808.  */
  809. payload_len = ntohs(skb->nh.ipv6h->payload_len);
  810. switch (msg->icmph.icmp6_type) {
  811. case NDISC_NEIGHBOUR_SOLICITATION:
  812. /* XXX: import nd_neighbor_solicit from glibc netinet/icmp6.h */
  813. if (payload_len < 8+16) {
  814. if (net_ratelimit())
  815. printk(KERN_WARNING "ICMP NS: packet too shortn");
  816. return 0;
  817. }
  818. if (ipv6_addr_type(&msg->target)&IPV6_ADDR_MULTICAST) {
  819. if (net_ratelimit())
  820. printk(KERN_WARNING "ICMP NS: target address is multicastn");
  821. return 0;
  822. }
  823. /* XXX: RFC2461 7.1.1:
  824.  *  If the IP source address is the unspecified address, there
  825.  * MUST NOT be source link-layer address option in the message.
  826.  *
  827.  * NOTE! Linux kernel < 2.4.4 broke this rule.
  828.  */
  829.  
  830. /* XXX: RFC2461 7.1.1:
  831.  * If the IP source address is the unspecified address, the IP
  832.         * destination address MUST be a solicited-node multicast address.
  833.  */
  834. if ((ifp = ipv6_get_ifaddr(&msg->target, dev)) != NULL) {
  835. int addr_type = ipv6_addr_type(saddr);
  836. if (ifp->flags & IFA_F_TENTATIVE) {
  837. /* Address is tentative. If the source
  838.    is unspecified address, it is someone
  839.    does DAD, otherwise we ignore solicitations
  840.    until DAD timer expires.
  841.  */
  842. if (addr_type == IPV6_ADDR_ANY) {
  843. if (dev->type == ARPHRD_IEEE802_TR) { 
  844. unsigned char *sadr = skb->mac.raw ;
  845. if (((sadr[8] &0x7f) != (dev->dev_addr[0] & 0x7f)) ||
  846. (sadr[9] != dev->dev_addr[1]) ||
  847. (sadr[10] != dev->dev_addr[2]) ||
  848. (sadr[11] != dev->dev_addr[3]) ||
  849. (sadr[12] != dev->dev_addr[4]) ||
  850. (sadr[13] != dev->dev_addr[5])) 
  851. {
  852. addrconf_dad_failure(ifp) ; 
  853. }
  854. } else {
  855. addrconf_dad_failure(ifp);
  856. }
  857. } else
  858. in6_ifa_put(ifp);
  859. return 0;
  860. }
  861. if (addr_type == IPV6_ADDR_ANY) {
  862. struct in6_addr maddr;
  863. ipv6_addr_all_nodes(&maddr);
  864. ndisc_send_na(dev, NULL, &maddr, &ifp->addr, 
  865.       ifp->idev->cnf.forwarding, 0, 
  866.       ipv6_addr_type(&ifp->addr)&IPV6_ADDR_ANYCAST ? 0 : 1, 
  867.       1);
  868. in6_ifa_put(ifp);
  869. return 0;
  870. }
  871. if (addr_type & IPV6_ADDR_UNICAST) {
  872. int inc = ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST;
  873. if (inc)
  874. nd_tbl.stats.rcv_probes_mcast++;
  875. else
  876. nd_tbl.stats.rcv_probes_ucast++;
  877. /* 
  878.  * update / create cache entry
  879.  * for the source adddress
  880.  */
  881. neigh = ndisc_recv_ns(saddr, skb);
  882. if (neigh) {
  883. ndisc_send_na(dev, neigh, saddr, &ifp->addr, 
  884.       ifp->idev->cnf.forwarding, 1, 
  885.       ipv6_addr_type(&ifp->addr)&IPV6_ADDR_ANYCAST ? 0 : 1, 
  886.       1);
  887. neigh_release(neigh);
  888. }
  889. }
  890. in6_ifa_put(ifp);
  891. } else {
  892. struct inet6_dev *in6_dev = in6_dev_get(dev);
  893. int addr_type = ipv6_addr_type(saddr);
  894. if (in6_dev && in6_dev->cnf.forwarding &&
  895.     (addr_type & IPV6_ADDR_UNICAST) &&
  896.     pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) {
  897. int inc = ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST;
  898. if (skb->stamp.tv_sec == 0 ||
  899.     skb->pkt_type == PACKET_HOST ||
  900.     inc == 0 ||
  901.     in6_dev->nd_parms->proxy_delay == 0) {
  902. if (inc)
  903. nd_tbl.stats.rcv_probes_mcast++;
  904. else
  905. nd_tbl.stats.rcv_probes_ucast++;
  906. neigh = ndisc_recv_ns(saddr, skb);
  907. if (neigh) {
  908. ndisc_send_na(dev, neigh, saddr, &msg->target,
  909.       0, 1, 0, 1);
  910. neigh_release(neigh);
  911. }
  912. } else {
  913. struct sk_buff *n = skb_clone(skb, GFP_ATOMIC);
  914. if (n)
  915. pneigh_enqueue(&nd_tbl, in6_dev->nd_parms, n);
  916. in6_dev_put(in6_dev);
  917. return 0;
  918. }
  919. }
  920. if (in6_dev)
  921. in6_dev_put(in6_dev);
  922. }
  923. return 0;
  924. case NDISC_NEIGHBOUR_ADVERTISEMENT:
  925. /* XXX: import nd_neighbor_advert from glibc netinet/icmp6.h */
  926. if (payload_len < 16+8 ) {
  927. if (net_ratelimit())
  928. printk(KERN_WARNING "ICMP NA: packet too shortn");
  929. return 0;
  930. }
  931. if (ipv6_addr_type(&msg->target)&IPV6_ADDR_MULTICAST) {
  932. if (net_ratelimit())
  933. printk(KERN_WARNING "NDISC NA: target address is multicastn");
  934. return 0;
  935. }
  936. if ((ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST) &&
  937.     msg->icmph.icmp6_solicited) {
  938. ND_PRINTK0("NDISC: solicited NA is multicastedn");
  939. return 0;
  940. }
  941. if ((ifp = ipv6_get_ifaddr(&msg->target, dev))) {
  942. if (ifp->flags & IFA_F_TENTATIVE) {
  943. addrconf_dad_failure(ifp);
  944. return 0;
  945. }
  946. /* What should we make now? The advertisement
  947.    is invalid, but ndisc specs say nothing
  948.    about it. It could be misconfiguration, or
  949.    an smart proxy agent tries to help us :-)
  950.  */
  951. ND_PRINTK0("%s: someone advertises our address!n",
  952.    ifp->idev->dev->name);
  953. in6_ifa_put(ifp);
  954. return 0;
  955. }
  956. neigh = neigh_lookup(&nd_tbl, &msg->target, skb->dev);
  957. if (neigh) {
  958. if (neigh->flags & NTF_ROUTER) {
  959. if (msg->icmph.icmp6_router == 0) {
  960. /*
  961.  * Change: router to host
  962.  */
  963. struct rt6_info *rt;
  964. rt = rt6_get_dflt_router(saddr, skb->dev);
  965. if (rt) {
  966. /* It is safe only because
  967.    we aer in BH */
  968. dst_release(&rt->u.dst);
  969. ip6_del_rt(rt);
  970. }
  971. }
  972. } else {
  973. if (msg->icmph.icmp6_router)
  974. neigh->flags |= NTF_ROUTER;
  975. }
  976. ndisc_recv_na(neigh, skb);
  977. neigh_release(neigh);
  978. }
  979. break;
  980. case NDISC_ROUTER_ADVERTISEMENT:
  981. /* XXX: import nd_router_advert from glibc netinet/icmp6.h */
  982. if (payload_len < 8+4+4) {
  983. if (net_ratelimit())
  984. printk(KERN_WARNING "ICMP RA: packet too shortn");
  985. return 0;
  986. }
  987. ndisc_router_discovery(skb);
  988. break;
  989. case NDISC_REDIRECT:
  990. /* XXX: import nd_redirect from glibc netinet/icmp6.h */
  991. if (payload_len < 8+16+16) {
  992. if (net_ratelimit())
  993. printk(KERN_WARNING "ICMP redirect: packet too shortn");
  994. return 0;
  995. }
  996. ndisc_redirect_rcv(skb);
  997. break;
  998. case NDISC_ROUTER_SOLICITATION:
  999. /* No RS support in the kernel, but we do some required checks */
  1000. /* XXX: import nd_router_solicit from glibc netinet/icmp6.h */
  1001. if (payload_len < 8) {
  1002. if (net_ratelimit())
  1003. printk(KERN_WARNING "ICMP RS: packet too shortn");
  1004. return 0;
  1005. }
  1006. break;
  1007. };
  1008. return 0;
  1009. }
  1010. int __init ndisc_init(struct net_proto_family *ops)
  1011. {
  1012. struct sock *sk;
  1013.         int err;
  1014. ndisc_socket = sock_alloc();
  1015. if (ndisc_socket == NULL) {
  1016. printk(KERN_ERR
  1017.        "Failed to create the NDISC control socket.n");
  1018. return -1;
  1019. }
  1020. ndisc_socket->inode->i_uid = 0;
  1021. ndisc_socket->inode->i_gid = 0;
  1022. ndisc_socket->type = SOCK_RAW;
  1023. if((err = ops->create(ndisc_socket, IPPROTO_ICMPV6)) < 0) {
  1024. printk(KERN_DEBUG 
  1025.        "Failed to initialize the NDISC control socket (err %d).n",
  1026.        err);
  1027. sock_release(ndisc_socket);
  1028. ndisc_socket = NULL; /* For safety. */
  1029. return err;
  1030. }
  1031. sk = ndisc_socket->sk;
  1032. sk->allocation = GFP_ATOMIC;
  1033. sk->net_pinfo.af_inet6.hop_limit = 255;
  1034. /* Do not loopback ndisc messages */
  1035. sk->net_pinfo.af_inet6.mc_loop = 0;
  1036. sk->prot->unhash(sk);
  1037.         /*
  1038.          * Initialize the neighbour table
  1039.          */
  1040. neigh_table_init(&nd_tbl);
  1041. #ifdef CONFIG_SYSCTL
  1042. neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, NET_IPV6_NEIGH, "ipv6");
  1043. #endif
  1044. return 0;
  1045. }
  1046. void ndisc_cleanup(void)
  1047. {
  1048. neigh_table_clear(&nd_tbl);
  1049. sock_release(ndisc_socket);
  1050. ndisc_socket = NULL; /* For safety. */
  1051. }