ndisc.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:32k
源码类别:

Linux/Unix编程

开发平台:

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