~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/ipv6/ndisc.c

Version: ~ [ linux-5.19-rc3 ] ~ [ linux-5.18.5 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.48 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.123 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.199 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.248 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.284 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.319 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.302 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 /*
 16  *      Changes:
 17  *
 18  *      Alexey I. Froloff               :       RFC6106 (DNSSL) support
 19  *      Pierre Ynard                    :       export userland ND options
 20  *                                              through netlink (RDNSS support)
 21  *      Lars Fenneberg                  :       fixed MTU setting on receipt
 22  *                                              of an RA.
 23  *      Janos Farkas                    :       kmalloc failure checks
 24  *      Alexey Kuznetsov                :       state machine reworked
 25  *                                              and moved to net/core.
 26  *      Pekka Savola                    :       RFC2461 validation
 27  *      YOSHIFUJI Hideaki @USAGI        :       Verify ND options properly
 28  */
 29 
 30 #define pr_fmt(fmt) "ICMPv6: " fmt
 31 
 32 #include <linux/module.h>
 33 #include <linux/errno.h>
 34 #include <linux/types.h>
 35 #include <linux/socket.h>
 36 #include <linux/sockios.h>
 37 #include <linux/sched.h>
 38 #include <linux/net.h>
 39 #include <linux/in6.h>
 40 #include <linux/route.h>
 41 #include <linux/init.h>
 42 #include <linux/rcupdate.h>
 43 #include <linux/slab.h>
 44 #ifdef CONFIG_SYSCTL
 45 #include <linux/sysctl.h>
 46 #endif
 47 
 48 #include <linux/if_addr.h>
 49 #include <linux/if_arp.h>
 50 #include <linux/ipv6.h>
 51 #include <linux/icmpv6.h>
 52 #include <linux/jhash.h>
 53 
 54 #include <net/sock.h>
 55 #include <net/snmp.h>
 56 
 57 #include <net/ipv6.h>
 58 #include <net/protocol.h>
 59 #include <net/ndisc.h>
 60 #include <net/ip6_route.h>
 61 #include <net/addrconf.h>
 62 #include <net/icmp.h>
 63 
 64 #include <net/netlink.h>
 65 #include <linux/rtnetlink.h>
 66 
 67 #include <net/flow.h>
 68 #include <net/ip6_checksum.h>
 69 #include <net/inet_common.h>
 70 #include <linux/proc_fs.h>
 71 
 72 #include <linux/netfilter.h>
 73 #include <linux/netfilter_ipv6.h>
 74 
 75 /* Set to 3 to get tracing... */
 76 #define ND_DEBUG 1
 77 
 78 #define ND_PRINTK(val, level, fmt, ...)                         \
 79 do {                                                            \
 80         if (val <= ND_DEBUG)                                    \
 81                 net_##level##_ratelimited(fmt, ##__VA_ARGS__);  \
 82 } while (0)
 83 
 84 static u32 ndisc_hash(const void *pkey,
 85                       const struct net_device *dev,
 86                       __u32 *hash_rnd);
 87 static bool ndisc_key_eq(const struct neighbour *neigh, const void *pkey);
 88 static int ndisc_constructor(struct neighbour *neigh);
 89 static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb);
 90 static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb);
 91 static int pndisc_constructor(struct pneigh_entry *n);
 92 static void pndisc_destructor(struct pneigh_entry *n);
 93 static void pndisc_redo(struct sk_buff *skb);
 94 
 95 static const struct neigh_ops ndisc_generic_ops = {
 96         .family =               AF_INET6,
 97         .solicit =              ndisc_solicit,
 98         .error_report =         ndisc_error_report,
 99         .output =               neigh_resolve_output,
100         .connected_output =     neigh_connected_output,
101 };
102 
103 static const struct neigh_ops ndisc_hh_ops = {
104         .family =               AF_INET6,
105         .solicit =              ndisc_solicit,
106         .error_report =         ndisc_error_report,
107         .output =               neigh_resolve_output,
108         .connected_output =     neigh_resolve_output,
109 };
110 
111 
112 static const struct neigh_ops ndisc_direct_ops = {
113         .family =               AF_INET6,
114         .output =               neigh_direct_output,
115         .connected_output =     neigh_direct_output,
116 };
117 
118 struct neigh_table nd_tbl = {
119         .family =       AF_INET6,
120         .key_len =      sizeof(struct in6_addr),
121         .protocol =     cpu_to_be16(ETH_P_IPV6),
122         .hash =         ndisc_hash,
123         .key_eq =       ndisc_key_eq,
124         .constructor =  ndisc_constructor,
125         .pconstructor = pndisc_constructor,
126         .pdestructor =  pndisc_destructor,
127         .proxy_redo =   pndisc_redo,
128         .id =           "ndisc_cache",
129         .parms = {
130                 .tbl                    = &nd_tbl,
131                 .reachable_time         = ND_REACHABLE_TIME,
132                 .data = {
133                         [NEIGH_VAR_MCAST_PROBES] = 3,
134                         [NEIGH_VAR_UCAST_PROBES] = 3,
135                         [NEIGH_VAR_RETRANS_TIME] = ND_RETRANS_TIMER,
136                         [NEIGH_VAR_BASE_REACHABLE_TIME] = ND_REACHABLE_TIME,
137                         [NEIGH_VAR_DELAY_PROBE_TIME] = 5 * HZ,
138                         [NEIGH_VAR_GC_STALETIME] = 60 * HZ,
139                         [NEIGH_VAR_QUEUE_LEN_BYTES] = 64 * 1024,
140                         [NEIGH_VAR_PROXY_QLEN] = 64,
141                         [NEIGH_VAR_ANYCAST_DELAY] = 1 * HZ,
142                         [NEIGH_VAR_PROXY_DELAY] = (8 * HZ) / 10,
143                 },
144         },
145         .gc_interval =    30 * HZ,
146         .gc_thresh1 =    128,
147         .gc_thresh2 =    512,
148         .gc_thresh3 =   1024,
149 };
150 
151 static void ndisc_fill_addr_option(struct sk_buff *skb, int type, void *data)
152 {
153         int pad   = ndisc_addr_option_pad(skb->dev->type);
154         int data_len = skb->dev->addr_len;
155         int space = ndisc_opt_addr_space(skb->dev);
156         u8 *opt = skb_put(skb, space);
157 
158         opt[0] = type;
159         opt[1] = space>>3;
160 
161         memset(opt + 2, 0, pad);
162         opt   += pad;
163         space -= pad;
164 
165         memcpy(opt+2, data, data_len);
166         data_len += 2;
167         opt += data_len;
168         space -= data_len;
169         if (space > 0)
170                 memset(opt, 0, space);
171 }
172 
173 static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
174                                             struct nd_opt_hdr *end)
175 {
176         int type;
177         if (!cur || !end || cur >= end)
178                 return NULL;
179         type = cur->nd_opt_type;
180         do {
181                 cur = ((void *)cur) + (cur->nd_opt_len << 3);
182         } while (cur < end && cur->nd_opt_type != type);
183         return cur <= end && cur->nd_opt_type == type ? cur : NULL;
184 }
185 
186 static inline int ndisc_is_useropt(struct nd_opt_hdr *opt)
187 {
188         return opt->nd_opt_type == ND_OPT_RDNSS ||
189                 opt->nd_opt_type == ND_OPT_DNSSL;
190 }
191 
192 static struct nd_opt_hdr *ndisc_next_useropt(struct nd_opt_hdr *cur,
193                                              struct nd_opt_hdr *end)
194 {
195         if (!cur || !end || cur >= end)
196                 return NULL;
197         do {
198                 cur = ((void *)cur) + (cur->nd_opt_len << 3);
199         } while (cur < end && !ndisc_is_useropt(cur));
200         return cur <= end && ndisc_is_useropt(cur) ? cur : NULL;
201 }
202 
203 struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
204                                           struct ndisc_options *ndopts)
205 {
206         struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)opt;
207 
208         if (!nd_opt || opt_len < 0 || !ndopts)
209                 return NULL;
210         memset(ndopts, 0, sizeof(*ndopts));
211         while (opt_len) {
212                 int l;
213                 if (opt_len < sizeof(struct nd_opt_hdr))
214                         return NULL;
215                 l = nd_opt->nd_opt_len << 3;
216                 if (opt_len < l || l == 0)
217                         return NULL;
218                 switch (nd_opt->nd_opt_type) {
219                 case ND_OPT_SOURCE_LL_ADDR:
220                 case ND_OPT_TARGET_LL_ADDR:
221                 case ND_OPT_MTU:
222                 case ND_OPT_REDIRECT_HDR:
223                         if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
224                                 ND_PRINTK(2, warn,
225                                           "%s: duplicated ND6 option found: type=%d\n",
226                                           __func__, nd_opt->nd_opt_type);
227                         } else {
228                                 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
229                         }
230                         break;
231                 case ND_OPT_PREFIX_INFO:
232                         ndopts->nd_opts_pi_end = nd_opt;
233                         if (!ndopts->nd_opt_array[nd_opt->nd_opt_type])
234                                 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
235                         break;
236 #ifdef CONFIG_IPV6_ROUTE_INFO
237                 case ND_OPT_ROUTE_INFO:
238                         ndopts->nd_opts_ri_end = nd_opt;
239                         if (!ndopts->nd_opts_ri)
240                                 ndopts->nd_opts_ri = nd_opt;
241                         break;
242 #endif
243                 default:
244                         if (ndisc_is_useropt(nd_opt)) {
245                                 ndopts->nd_useropts_end = nd_opt;
246                                 if (!ndopts->nd_useropts)
247                                         ndopts->nd_useropts = nd_opt;
248                         } else {
249                                 /*
250                                  * Unknown options must be silently ignored,
251                                  * to accommodate future extension to the
252                                  * protocol.
253                                  */
254                                 ND_PRINTK(2, notice,
255                                           "%s: ignored unsupported option; type=%d, len=%d\n",
256                                           __func__,
257                                           nd_opt->nd_opt_type,
258                                           nd_opt->nd_opt_len);
259                         }
260                 }
261                 opt_len -= l;
262                 nd_opt = ((void *)nd_opt) + l;
263         }
264         return ndopts;
265 }
266 
267 int ndisc_mc_map(const struct in6_addr *addr, char *buf, struct net_device *dev, int dir)
268 {
269         switch (dev->type) {
270         case ARPHRD_ETHER:
271         case ARPHRD_IEEE802:    /* Not sure. Check it later. --ANK */
272         case ARPHRD_FDDI:
273                 ipv6_eth_mc_map(addr, buf);
274                 return 0;
275         case ARPHRD_ARCNET:
276                 ipv6_arcnet_mc_map(addr, buf);
277                 return 0;
278         case ARPHRD_INFINIBAND:
279                 ipv6_ib_mc_map(addr, dev->broadcast, buf);
280                 return 0;
281         case ARPHRD_IPGRE:
282                 return ipv6_ipgre_mc_map(addr, dev->broadcast, buf);
283         default:
284                 if (dir) {
285                         memcpy(buf, dev->broadcast, dev->addr_len);
286                         return 0;
287                 }
288         }
289         return -EINVAL;
290 }
291 EXPORT_SYMBOL(ndisc_mc_map);
292 
293 static u32 ndisc_hash(const void *pkey,
294                       const struct net_device *dev,
295                       __u32 *hash_rnd)
296 {
297         return ndisc_hashfn(pkey, dev, hash_rnd);
298 }
299 
300 static bool ndisc_key_eq(const struct neighbour *n, const void *pkey)
301 {
302         return neigh_key_eq128(n, pkey);
303 }
304 
305 static int ndisc_constructor(struct neighbour *neigh)
306 {
307         struct in6_addr *addr = (struct in6_addr *)&neigh->primary_key;
308         struct net_device *dev = neigh->dev;
309         struct inet6_dev *in6_dev;
310         struct neigh_parms *parms;
311         bool is_multicast = ipv6_addr_is_multicast(addr);
312 
313         in6_dev = in6_dev_get(dev);
314         if (!in6_dev) {
315                 return -EINVAL;
316         }
317 
318         parms = in6_dev->nd_parms;
319         __neigh_parms_put(neigh->parms);
320         neigh->parms = neigh_parms_clone(parms);
321 
322         neigh->type = is_multicast ? RTN_MULTICAST : RTN_UNICAST;
323         if (!dev->header_ops) {
324                 neigh->nud_state = NUD_NOARP;
325                 neigh->ops = &ndisc_direct_ops;
326                 neigh->output = neigh_direct_output;
327         } else {
328                 if (is_multicast) {
329                         neigh->nud_state = NUD_NOARP;
330                         ndisc_mc_map(addr, neigh->ha, dev, 1);
331                 } else if (dev->flags&(IFF_NOARP|IFF_LOOPBACK)) {
332                         neigh->nud_state = NUD_NOARP;
333                         memcpy(neigh->ha, dev->dev_addr, dev->addr_len);
334                         if (dev->flags&IFF_LOOPBACK)
335                                 neigh->type = RTN_LOCAL;
336                 } else if (dev->flags&IFF_POINTOPOINT) {
337                         neigh->nud_state = NUD_NOARP;
338                         memcpy(neigh->ha, dev->broadcast, dev->addr_len);
339                 }
340                 if (dev->header_ops->cache)
341                         neigh->ops = &ndisc_hh_ops;
342                 else
343                         neigh->ops = &ndisc_generic_ops;
344                 if (neigh->nud_state&NUD_VALID)
345                         neigh->output = neigh->ops->connected_output;
346                 else
347                         neigh->output = neigh->ops->output;
348         }
349         in6_dev_put(in6_dev);
350         return 0;
351 }
352 
353 static int pndisc_constructor(struct pneigh_entry *n)
354 {
355         struct in6_addr *addr = (struct in6_addr *)&n->key;
356         struct in6_addr maddr;
357         struct net_device *dev = n->dev;
358 
359         if (!dev || !__in6_dev_get(dev))
360                 return -EINVAL;
361         addrconf_addr_solict_mult(addr, &maddr);
362         ipv6_dev_mc_inc(dev, &maddr);
363         return 0;
364 }
365 
366 static void pndisc_destructor(struct pneigh_entry *n)
367 {
368         struct in6_addr *addr = (struct in6_addr *)&n->key;
369         struct in6_addr maddr;
370         struct net_device *dev = n->dev;
371 
372         if (!dev || !__in6_dev_get(dev))
373                 return;
374         addrconf_addr_solict_mult(addr, &maddr);
375         ipv6_dev_mc_dec(dev, &maddr);
376 }
377 
378 static struct sk_buff *ndisc_alloc_skb(struct net_device *dev,
379                                        int len)
380 {
381         int hlen = LL_RESERVED_SPACE(dev);
382         int tlen = dev->needed_tailroom;
383         struct sock *sk = dev_net(dev)->ipv6.ndisc_sk;
384         struct sk_buff *skb;
385 
386         skb = alloc_skb(hlen + sizeof(struct ipv6hdr) + len + tlen, GFP_ATOMIC);
387         if (!skb) {
388                 ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb\n",
389                           __func__);
390                 return NULL;
391         }
392 
393         skb->protocol = htons(ETH_P_IPV6);
394         skb->dev = dev;
395 
396         skb_reserve(skb, hlen + sizeof(struct ipv6hdr));
397         skb_reset_transport_header(skb);
398 
399         /* Manually assign socket ownership as we avoid calling
400          * sock_alloc_send_pskb() to bypass wmem buffer limits
401          */
402         skb_set_owner_w(skb, sk);
403 
404         return skb;
405 }
406 
407 static void ip6_nd_hdr(struct sk_buff *skb,
408                        const struct in6_addr *saddr,
409                        const struct in6_addr *daddr,
410                        int hop_limit, int len)
411 {
412         struct ipv6hdr *hdr;
413 
414         skb_push(skb, sizeof(*hdr));
415         skb_reset_network_header(skb);
416         hdr = ipv6_hdr(skb);
417 
418         ip6_flow_hdr(hdr, 0, 0);
419 
420         hdr->payload_len = htons(len);
421         hdr->nexthdr = IPPROTO_ICMPV6;
422         hdr->hop_limit = hop_limit;
423 
424         hdr->saddr = *saddr;
425         hdr->daddr = *daddr;
426 }
427 
428 static void ndisc_send_skb(struct sk_buff *skb,
429                            const struct in6_addr *daddr,
430                            const struct in6_addr *saddr)
431 {
432         struct dst_entry *dst = skb_dst(skb);
433         struct net *net = dev_net(skb->dev);
434         struct sock *sk = net->ipv6.ndisc_sk;
435         struct inet6_dev *idev;
436         int err;
437         struct icmp6hdr *icmp6h = icmp6_hdr(skb);
438         u8 type;
439 
440         type = icmp6h->icmp6_type;
441 
442         if (!dst) {
443                 struct flowi6 fl6;
444 
445                 icmpv6_flow_init(sk, &fl6, type, saddr, daddr, skb->dev->ifindex);
446                 dst = icmp6_dst_alloc(skb->dev, &fl6);
447                 if (IS_ERR(dst)) {
448                         kfree_skb(skb);
449                         return;
450                 }
451 
452                 skb_dst_set(skb, dst);
453         }
454 
455         icmp6h->icmp6_cksum = csum_ipv6_magic(saddr, daddr, skb->len,
456                                               IPPROTO_ICMPV6,
457                                               csum_partial(icmp6h,
458                                                            skb->len, 0));
459 
460         ip6_nd_hdr(skb, saddr, daddr, inet6_sk(sk)->hop_limit, skb->len);
461 
462         rcu_read_lock();
463         idev = __in6_dev_get(dst->dev);
464         IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
465 
466         err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, sk, skb,
467                       NULL, dst->dev,
468                       dst_output_sk);
469         if (!err) {
470                 ICMP6MSGOUT_INC_STATS(net, idev, type);
471                 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
472         }
473 
474         rcu_read_unlock();
475 }
476 
477 void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
478                    const struct in6_addr *daddr,
479                    const struct in6_addr *solicited_addr,
480                    bool router, bool solicited, bool override, bool inc_opt)
481 {
482         struct sk_buff *skb;
483         struct in6_addr tmpaddr;
484         struct inet6_ifaddr *ifp;
485         const struct in6_addr *src_addr;
486         struct nd_msg *msg;
487         int optlen = 0;
488 
489         /* for anycast or proxy, solicited_addr != src_addr */
490         ifp = ipv6_get_ifaddr(dev_net(dev), solicited_addr, dev, 1);
491         if (ifp) {
492                 src_addr = solicited_addr;
493                 if (ifp->flags & IFA_F_OPTIMISTIC)
494                         override = false;
495                 inc_opt |= ifp->idev->cnf.force_tllao;
496                 in6_ifa_put(ifp);
497         } else {
498                 if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
499                                        inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs,
500                                        &tmpaddr))
501                         return;
502                 src_addr = &tmpaddr;
503         }
504 
505         if (!dev->addr_len)
506                 inc_opt = 0;
507         if (inc_opt)
508                 optlen += ndisc_opt_addr_space(dev);
509 
510         skb = ndisc_alloc_skb(dev, sizeof(*msg) + optlen);
511         if (!skb)
512                 return;
513 
514         msg = (struct nd_msg *)skb_put(skb, sizeof(*msg));
515         *msg = (struct nd_msg) {
516                 .icmph = {
517                         .icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT,
518                         .icmp6_router = router,
519                         .icmp6_solicited = solicited,
520                         .icmp6_override = override,
521                 },
522                 .target = *solicited_addr,
523         };
524 
525         if (inc_opt)
526                 ndisc_fill_addr_option(skb, ND_OPT_TARGET_LL_ADDR,
527                                        dev->dev_addr);
528 
529 
530         ndisc_send_skb(skb, daddr, src_addr);
531 }
532 
533 static void ndisc_send_unsol_na(struct net_device *dev)
534 {
535         struct inet6_dev *idev;
536         struct inet6_ifaddr *ifa;
537 
538         idev = in6_dev_get(dev);
539         if (!idev)
540                 return;
541 
542         read_lock_bh(&idev->lock);
543         list_for_each_entry(ifa, &idev->addr_list, if_list) {
544                 ndisc_send_na(dev, NULL, &in6addr_linklocal_allnodes, &ifa->addr,
545                               /*router=*/ !!idev->cnf.forwarding,
546                               /*solicited=*/ false, /*override=*/ true,
547                               /*inc_opt=*/ true);
548         }
549         read_unlock_bh(&idev->lock);
550 
551         in6_dev_put(idev);
552 }
553 
554 void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
555                    const struct in6_addr *solicit,
556                    const struct in6_addr *daddr, const struct in6_addr *saddr)
557 {
558         struct sk_buff *skb;
559         struct in6_addr addr_buf;
560         int inc_opt = dev->addr_len;
561         int optlen = 0;
562         struct nd_msg *msg;
563 
564         if (!saddr) {
565                 if (ipv6_get_lladdr(dev, &addr_buf,
566                                    (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)))
567                         return;
568                 saddr = &addr_buf;
569         }
570 
571         if (ipv6_addr_any(saddr))
572                 inc_opt = false;
573         if (inc_opt)
574                 optlen += ndisc_opt_addr_space(dev);
575 
576         skb = ndisc_alloc_skb(dev, sizeof(*msg) + optlen);
577         if (!skb)
578                 return;
579 
580         msg = (struct nd_msg *)skb_put(skb, sizeof(*msg));
581         *msg = (struct nd_msg) {
582                 .icmph = {
583                         .icmp6_type = NDISC_NEIGHBOUR_SOLICITATION,
584                 },
585                 .target = *solicit,
586         };
587 
588         if (inc_opt)
589                 ndisc_fill_addr_option(skb, ND_OPT_SOURCE_LL_ADDR,
590                                        dev->dev_addr);
591 
592         ndisc_send_skb(skb, daddr, saddr);
593 }
594 
595 void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
596                    const struct in6_addr *daddr)
597 {
598         struct sk_buff *skb;
599         struct rs_msg *msg;
600         int send_sllao = dev->addr_len;
601         int optlen = 0;
602 
603 #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
604         /*
605          * According to section 2.2 of RFC 4429, we must not
606          * send router solicitations with a sllao from
607          * optimistic addresses, but we may send the solicitation
608          * if we don't include the sllao.  So here we check
609          * if our address is optimistic, and if so, we
610          * suppress the inclusion of the sllao.
611          */
612         if (send_sllao) {
613                 struct inet6_ifaddr *ifp = ipv6_get_ifaddr(dev_net(dev), saddr,
614                                                            dev, 1);
615                 if (ifp) {
616                         if (ifp->flags & IFA_F_OPTIMISTIC)  {
617                                 send_sllao = 0;
618                         }
619                         in6_ifa_put(ifp);
620                 } else {
621                         send_sllao = 0;
622                 }
623         }
624 #endif
625         if (send_sllao)
626                 optlen += ndisc_opt_addr_space(dev);
627 
628         skb = ndisc_alloc_skb(dev, sizeof(*msg) + optlen);
629         if (!skb)
630                 return;
631 
632         msg = (struct rs_msg *)skb_put(skb, sizeof(*msg));
633         *msg = (struct rs_msg) {
634                 .icmph = {
635                         .icmp6_type = NDISC_ROUTER_SOLICITATION,
636                 },
637         };
638 
639         if (send_sllao)
640                 ndisc_fill_addr_option(skb, ND_OPT_SOURCE_LL_ADDR,
641                                        dev->dev_addr);
642 
643         ndisc_send_skb(skb, daddr, saddr);
644 }
645 
646 
647 static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb)
648 {
649         /*
650          *      "The sender MUST return an ICMP
651          *       destination unreachable"
652          */
653         dst_link_failure(skb);
654         kfree_skb(skb);
655 }
656 
657 /* Called with locked neigh: either read or both */
658 
659 static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
660 {
661         struct in6_addr *saddr = NULL;
662         struct in6_addr mcaddr;
663         struct net_device *dev = neigh->dev;
664         struct in6_addr *target = (struct in6_addr *)&neigh->primary_key;
665         int probes = atomic_read(&neigh->probes);
666 
667         if (skb && ipv6_chk_addr_and_flags(dev_net(dev), &ipv6_hdr(skb)->saddr,
668                                            dev, 1,
669                                            IFA_F_TENTATIVE|IFA_F_OPTIMISTIC))
670                 saddr = &ipv6_hdr(skb)->saddr;
671         probes -= NEIGH_VAR(neigh->parms, UCAST_PROBES);
672         if (probes < 0) {
673                 if (!(neigh->nud_state & NUD_VALID)) {
674                         ND_PRINTK(1, dbg,
675                                   "%s: trying to ucast probe in NUD_INVALID: %pI6\n",
676                                   __func__, target);
677                 }
678                 ndisc_send_ns(dev, neigh, target, target, saddr);
679         } else if ((probes -= NEIGH_VAR(neigh->parms, APP_PROBES)) < 0) {
680                 neigh_app_ns(neigh);
681         } else {
682                 addrconf_addr_solict_mult(target, &mcaddr);
683                 ndisc_send_ns(dev, NULL, target, &mcaddr, saddr);
684         }
685 }
686 
687 static int pndisc_is_router(const void *pkey,
688                             struct net_device *dev)
689 {
690         struct pneigh_entry *n;
691         int ret = -1;
692 
693         read_lock_bh(&nd_tbl.lock);
694         n = __pneigh_lookup(&nd_tbl, dev_net(dev), pkey, dev);
695         if (n)
696                 ret = !!(n->flags & NTF_ROUTER);
697         read_unlock_bh(&nd_tbl.lock);
698 
699         return ret;
700 }
701 
702 static void ndisc_recv_ns(struct sk_buff *skb)
703 {
704         struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb);
705         const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
706         const struct in6_addr *daddr = &ipv6_hdr(skb)->daddr;
707         u8 *lladdr = NULL;
708         u32 ndoptlen = skb_tail_pointer(skb) - (skb_transport_header(skb) +
709                                     offsetof(struct nd_msg, opt));
710         struct ndisc_options ndopts;
711         struct net_device *dev = skb->dev;
712         struct inet6_ifaddr *ifp;
713         struct inet6_dev *idev = NULL;
714         struct neighbour *neigh;
715         int dad = ipv6_addr_any(saddr);
716         bool inc;
717         int is_router = -1;
718 
719         if (skb->len < sizeof(struct nd_msg)) {
720                 ND_PRINTK(2, warn, "NS: packet too short\n");
721                 return;
722         }
723 
724         if (ipv6_addr_is_multicast(&msg->target)) {
725                 ND_PRINTK(2, warn, "NS: multicast target address\n");
726                 return;
727         }
728 
729         /*
730          * RFC2461 7.1.1:
731          * DAD has to be destined for solicited node multicast address.
732          */
733         if (dad && !ipv6_addr_is_solict_mult(daddr)) {
734                 ND_PRINTK(2, warn, "NS: bad DAD packet (wrong destination)\n");
735                 return;
736         }
737 
738         if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
739                 ND_PRINTK(2, warn, "NS: invalid ND options\n");
740                 return;
741         }
742 
743         if (ndopts.nd_opts_src_lladdr) {
744                 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr, dev);
745                 if (!lladdr) {
746                         ND_PRINTK(2, warn,
747                                   "NS: invalid link-layer address length\n");
748                         return;
749                 }
750 
751                 /* RFC2461 7.1.1:
752                  *      If the IP source address is the unspecified address,
753                  *      there MUST NOT be source link-layer address option
754                  *      in the message.
755                  */
756                 if (dad) {
757                         ND_PRINTK(2, warn,
758                                   "NS: bad DAD packet (link-layer address option)\n");
759                         return;
760                 }
761         }
762 
763         inc = ipv6_addr_is_multicast(daddr);
764 
765         ifp = ipv6_get_ifaddr(dev_net(dev), &msg->target, dev, 1);
766         if (ifp) {
767 
768                 if (ifp->flags & (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)) {
769                         if (dad) {
770                                 /*
771                                  * We are colliding with another node
772                                  * who is doing DAD
773                                  * so fail our DAD process
774                                  */
775                                 addrconf_dad_failure(ifp);
776                                 return;
777                         } else {
778                                 /*
779                                  * This is not a dad solicitation.
780                                  * If we are an optimistic node,
781                                  * we should respond.
782                                  * Otherwise, we should ignore it.
783                                  */
784                                 if (!(ifp->flags & IFA_F_OPTIMISTIC))
785                                         goto out;
786                         }
787                 }
788 
789                 idev = ifp->idev;
790         } else {
791                 struct net *net = dev_net(dev);
792 
793                 idev = in6_dev_get(dev);
794                 if (!idev) {
795                         /* XXX: count this drop? */
796                         return;
797                 }
798 
799                 if (ipv6_chk_acast_addr(net, dev, &msg->target) ||
800                     (idev->cnf.forwarding &&
801                      (net->ipv6.devconf_all->proxy_ndp || idev->cnf.proxy_ndp) &&
802                      (is_router = pndisc_is_router(&msg->target, dev)) >= 0)) {
803                         if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
804                             skb->pkt_type != PACKET_HOST &&
805                             inc &&
806                             NEIGH_VAR(idev->nd_parms, PROXY_DELAY) != 0) {
807                                 /*
808                                  * for anycast or proxy,
809                                  * sender should delay its response
810                                  * by a random time between 0 and
811                                  * MAX_ANYCAST_DELAY_TIME seconds.
812                                  * (RFC2461) -- yoshfuji
813                                  */
814                                 struct sk_buff *n = skb_clone(skb, GFP_ATOMIC);
815                                 if (n)
816                                         pneigh_enqueue(&nd_tbl, idev->nd_parms, n);
817                                 goto out;
818                         }
819                 } else
820                         goto out;
821         }
822 
823         if (is_router < 0)
824                 is_router = idev->cnf.forwarding;
825 
826         if (dad) {
827                 ndisc_send_na(dev, NULL, &in6addr_linklocal_allnodes, &msg->target,
828                               !!is_router, false, (ifp != NULL), true);
829                 goto out;
830         }
831 
832         if (inc)
833                 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_mcast);
834         else
835                 NEIGH_CACHE_STAT_INC(&nd_tbl, rcv_probes_ucast);
836 
837         /*
838          *      update / create cache entry
839          *      for the source address
840          */
841         neigh = __neigh_lookup(&nd_tbl, saddr, dev,
842                                !inc || lladdr || !dev->addr_len);
843         if (neigh)
844                 neigh_update(neigh, lladdr, NUD_STALE,
845                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
846                              NEIGH_UPDATE_F_OVERRIDE);
847         if (neigh || !dev->header_ops) {
848                 ndisc_send_na(dev, neigh, saddr, &msg->target,
849                               !!is_router,
850                               true, (ifp != NULL && inc), inc);
851                 if (neigh)
852                         neigh_release(neigh);
853         }
854 
855 out:
856         if (ifp)
857                 in6_ifa_put(ifp);
858         else
859                 in6_dev_put(idev);
860 }
861 
862 static void ndisc_recv_na(struct sk_buff *skb)
863 {
864         struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb);
865         struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
866         const struct in6_addr *daddr = &ipv6_hdr(skb)->daddr;
867         u8 *lladdr = NULL;
868         u32 ndoptlen = skb_tail_pointer(skb) - (skb_transport_header(skb) +
869                                     offsetof(struct nd_msg, opt));
870         struct ndisc_options ndopts;
871         struct net_device *dev = skb->dev;
872         struct inet6_ifaddr *ifp;
873         struct neighbour *neigh;
874 
875         if (skb->len < sizeof(struct nd_msg)) {
876                 ND_PRINTK(2, warn, "NA: packet too short\n");
877                 return;
878         }
879 
880         if (ipv6_addr_is_multicast(&msg->target)) {
881                 ND_PRINTK(2, warn, "NA: target address is multicast\n");
882                 return;
883         }
884 
885         if (ipv6_addr_is_multicast(daddr) &&
886             msg->icmph.icmp6_solicited) {
887                 ND_PRINTK(2, warn, "NA: solicited NA is multicasted\n");
888                 return;
889         }
890 
891         if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
892                 ND_PRINTK(2, warn, "NS: invalid ND option\n");
893                 return;
894         }
895         if (ndopts.nd_opts_tgt_lladdr) {
896                 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_tgt_lladdr, dev);
897                 if (!lladdr) {
898                         ND_PRINTK(2, warn,
899                                   "NA: invalid link-layer address length\n");
900                         return;
901                 }
902         }
903         ifp = ipv6_get_ifaddr(dev_net(dev), &msg->target, dev, 1);
904         if (ifp) {
905                 if (skb->pkt_type != PACKET_LOOPBACK
906                     && (ifp->flags & IFA_F_TENTATIVE)) {
907                                 addrconf_dad_failure(ifp);
908                                 return;
909                 }
910                 /* What should we make now? The advertisement
911                    is invalid, but ndisc specs say nothing
912                    about it. It could be misconfiguration, or
913                    an smart proxy agent tries to help us :-)
914 
915                    We should not print the error if NA has been
916                    received from loopback - it is just our own
917                    unsolicited advertisement.
918                  */
919                 if (skb->pkt_type != PACKET_LOOPBACK)
920                         ND_PRINTK(1, warn,
921                                   "NA: someone advertises our address %pI6 on %s!\n",
922                                   &ifp->addr, ifp->idev->dev->name);
923                 in6_ifa_put(ifp);
924                 return;
925         }
926         neigh = neigh_lookup(&nd_tbl, &msg->target, dev);
927 
928         if (neigh) {
929                 u8 old_flags = neigh->flags;
930                 struct net *net = dev_net(dev);
931 
932                 if (neigh->nud_state & NUD_FAILED)
933                         goto out;
934 
935                 /*
936                  * Don't update the neighbor cache entry on a proxy NA from
937                  * ourselves because either the proxied node is off link or it
938                  * has already sent a NA to us.
939                  */
940                 if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
941                     net->ipv6.devconf_all->forwarding && net->ipv6.devconf_all->proxy_ndp &&
942                     pneigh_lookup(&nd_tbl, net, &msg->target, dev, 0)) {
943                         /* XXX: idev->cnf.proxy_ndp */
944                         goto out;
945                 }
946 
947                 neigh_update(neigh, lladdr,
948                              msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
949                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
950                              (msg->icmph.icmp6_override ? NEIGH_UPDATE_F_OVERRIDE : 0)|
951                              NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
952                              (msg->icmph.icmp6_router ? NEIGH_UPDATE_F_ISROUTER : 0));
953 
954                 if ((old_flags & ~neigh->flags) & NTF_ROUTER) {
955                         /*
956                          * Change: router to host
957                          */
958                         rt6_clean_tohost(dev_net(dev),  saddr);
959                 }
960 
961 out:
962                 neigh_release(neigh);
963         }
964 }
965 
966 static void ndisc_recv_rs(struct sk_buff *skb)
967 {
968         struct rs_msg *rs_msg = (struct rs_msg *)skb_transport_header(skb);
969         unsigned long ndoptlen = skb->len - sizeof(*rs_msg);
970         struct neighbour *neigh;
971         struct inet6_dev *idev;
972         const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
973         struct ndisc_options ndopts;
974         u8 *lladdr = NULL;
975 
976         if (skb->len < sizeof(*rs_msg))
977                 return;
978 
979         idev = __in6_dev_get(skb->dev);
980         if (!idev) {
981                 ND_PRINTK(1, err, "RS: can't find in6 device\n");
982                 return;
983         }
984 
985         /* Don't accept RS if we're not in router mode */
986         if (!idev->cnf.forwarding)
987                 goto out;
988 
989         /*
990          * Don't update NCE if src = ::;
991          * this implies that the source node has no ip address assigned yet.
992          */
993         if (ipv6_addr_any(saddr))
994                 goto out;
995 
996         /* Parse ND options */
997         if (!ndisc_parse_options(rs_msg->opt, ndoptlen, &ndopts)) {
998                 ND_PRINTK(2, notice, "NS: invalid ND option, ignored\n");
999                 goto out;
1000         }
1001 
1002         if (ndopts.nd_opts_src_lladdr) {
1003                 lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr,
1004                                              skb->dev);
1005                 if (!lladdr)
1006                         goto out;
1007         }
1008 
1009         neigh = __neigh_lookup(&nd_tbl, saddr, skb->dev, 1);
1010         if (neigh) {
1011                 neigh_update(neigh, lladdr, NUD_STALE,
1012                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
1013                              NEIGH_UPDATE_F_OVERRIDE|
1014                              NEIGH_UPDATE_F_OVERRIDE_ISROUTER);
1015                 neigh_release(neigh);
1016         }
1017 out:
1018         return;
1019 }
1020 
1021 static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt)
1022 {
1023         struct icmp6hdr *icmp6h = (struct icmp6hdr *)skb_transport_header(ra);
1024         struct sk_buff *skb;
1025         struct nlmsghdr *nlh;
1026         struct nduseroptmsg *ndmsg;
1027         struct net *net = dev_net(ra->dev);
1028         int err;
1029         int base_size = NLMSG_ALIGN(sizeof(struct nduseroptmsg)
1030                                     + (opt->nd_opt_len << 3));
1031         size_t msg_size = base_size + nla_total_size(sizeof(struct in6_addr));
1032 
1033         skb = nlmsg_new(msg_size, GFP_ATOMIC);
1034         if (!skb) {
1035                 err = -ENOBUFS;
1036                 goto errout;
1037         }
1038 
1039         nlh = nlmsg_put(skb, 0, 0, RTM_NEWNDUSEROPT, base_size, 0);
1040         if (!nlh) {
1041                 goto nla_put_failure;
1042         }
1043 
1044         ndmsg = nlmsg_data(nlh);
1045         ndmsg->nduseropt_family = AF_INET6;
1046         ndmsg->nduseropt_ifindex = ra->dev->ifindex;
1047         ndmsg->nduseropt_icmp_type = icmp6h->icmp6_type;
1048         ndmsg->nduseropt_icmp_code = icmp6h->icmp6_code;
1049         ndmsg->nduseropt_opts_len = opt->nd_opt_len << 3;
1050 
1051         memcpy(ndmsg + 1, opt, opt->nd_opt_len << 3);
1052 
1053         if (nla_put_in6_addr(skb, NDUSEROPT_SRCADDR, &ipv6_hdr(ra)->saddr))
1054                 goto nla_put_failure;
1055         nlmsg_end(skb, nlh);
1056 
1057         rtnl_notify(skb, net, 0, RTNLGRP_ND_USEROPT, NULL, GFP_ATOMIC);
1058         return;
1059 
1060 nla_put_failure:
1061         nlmsg_free(skb);
1062         err = -EMSGSIZE;
1063 errout:
1064         rtnl_set_sk_err(net, RTNLGRP_ND_USEROPT, err);
1065 }
1066 
1067 static void ndisc_router_discovery(struct sk_buff *skb)
1068 {
1069         struct ra_msg *ra_msg = (struct ra_msg *)skb_transport_header(skb);
1070         struct neighbour *neigh = NULL;
1071         struct inet6_dev *in6_dev;
1072         struct rt6_info *rt = NULL;
1073         int lifetime;
1074         struct ndisc_options ndopts;
1075         int optlen;
1076         unsigned int pref = 0;
1077 
1078         __u8 *opt = (__u8 *)(ra_msg + 1);
1079 
1080         optlen = (skb_tail_pointer(skb) - skb_transport_header(skb)) -
1081                 sizeof(struct ra_msg);
1082 
1083         ND_PRINTK(2, info,
1084                   "RA: %s, dev: %s\n",
1085                   __func__, skb->dev->name);
1086         if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) {
1087                 ND_PRINTK(2, warn, "RA: source address is not link-local\n");
1088                 return;
1089         }
1090         if (optlen < 0) {
1091                 ND_PRINTK(2, warn, "RA: packet too short\n");
1092                 return;
1093         }
1094 
1095 #ifdef CONFIG_IPV6_NDISC_NODETYPE
1096         if (skb->ndisc_nodetype == NDISC_NODETYPE_HOST) {
1097                 ND_PRINTK(2, warn, "RA: from host or unauthorized router\n");
1098                 return;
1099         }
1100 #endif
1101 
1102         /*
1103          *      set the RA_RECV flag in the interface
1104          */
1105 
1106         in6_dev = __in6_dev_get(skb->dev);
1107         if (!in6_dev) {
1108                 ND_PRINTK(0, err, "RA: can't find inet6 device for %s\n",
1109                           skb->dev->name);
1110                 return;
1111         }
1112 
1113         if (!ndisc_parse_options(opt, optlen, &ndopts)) {
1114                 ND_PRINTK(2, warn, "RA: invalid ND options\n");
1115                 return;
1116         }
1117 
1118         if (!ipv6_accept_ra(in6_dev)) {
1119                 ND_PRINTK(2, info,
1120                           "RA: %s, did not accept ra for dev: %s\n",
1121                           __func__, skb->dev->name);
1122                 goto skip_linkparms;
1123         }
1124 
1125 #ifdef CONFIG_IPV6_NDISC_NODETYPE
1126         /* skip link-specific parameters from interior routers */
1127         if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT) {
1128                 ND_PRINTK(2, info,
1129                           "RA: %s, nodetype is NODEFAULT, dev: %s\n",
1130                           __func__, skb->dev->name);
1131                 goto skip_linkparms;
1132         }
1133 #endif
1134 
1135         if (in6_dev->if_flags & IF_RS_SENT) {
1136                 /*
1137                  *      flag that an RA was received after an RS was sent
1138                  *      out on this interface.
1139                  */
1140                 in6_dev->if_flags |= IF_RA_RCVD;
1141         }
1142 
1143         /*
1144          * Remember the managed/otherconf flags from most recently
1145          * received RA message (RFC 2462) -- yoshfuji
1146          */
1147         in6_dev->if_flags = (in6_dev->if_flags & ~(IF_RA_MANAGED |
1148                                 IF_RA_OTHERCONF)) |
1149                                 (ra_msg->icmph.icmp6_addrconf_managed ?
1150                                         IF_RA_MANAGED : 0) |
1151                                 (ra_msg->icmph.icmp6_addrconf_other ?
1152                                         IF_RA_OTHERCONF : 0);
1153 
1154         if (!in6_dev->cnf.accept_ra_defrtr) {
1155                 ND_PRINTK(2, info,
1156                           "RA: %s, defrtr is false for dev: %s\n",
1157                           __func__, skb->dev->name);
1158                 goto skip_defrtr;
1159         }
1160 
1161         /* Do not accept RA with source-addr found on local machine unless
1162          * accept_ra_from_local is set to true.
1163          */
1164         if (!in6_dev->cnf.accept_ra_from_local &&
1165             ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr,
1166                           NULL, 0)) {
1167                 ND_PRINTK(2, info,
1168                           "RA from local address detected on dev: %s: default router ignored\n",
1169                           skb->dev->name);
1170                 goto skip_defrtr;
1171         }
1172 
1173         lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);
1174 
1175 #ifdef CONFIG_IPV6_ROUTER_PREF
1176         pref = ra_msg->icmph.icmp6_router_pref;
1177         /* 10b is handled as if it were 00b (medium) */
1178         if (pref == ICMPV6_ROUTER_PREF_INVALID ||
1179             !in6_dev->cnf.accept_ra_rtr_pref)
1180                 pref = ICMPV6_ROUTER_PREF_MEDIUM;
1181 #endif
1182 
1183         rt = rt6_get_dflt_router(&ipv6_hdr(skb)->saddr, skb->dev);
1184 
1185         if (rt) {
1186                 neigh = dst_neigh_lookup(&rt->dst, &ipv6_hdr(skb)->saddr);
1187                 if (!neigh) {
1188                         ND_PRINTK(0, err,
1189                                   "RA: %s got default router without neighbour\n",
1190                                   __func__);
1191                         ip6_rt_put(rt);
1192                         return;
1193                 }
1194         }
1195         if (rt && lifetime == 0) {
1196                 ip6_del_rt(rt);
1197                 rt = NULL;
1198         }
1199 
1200         ND_PRINTK(3, info, "RA: rt: %p  lifetime: %d, for dev: %s\n",
1201                   rt, lifetime, skb->dev->name);
1202         if (!rt && lifetime) {
1203                 ND_PRINTK(3, info, "RA: adding default router\n");
1204 
1205                 rt = rt6_add_dflt_router(&ipv6_hdr(skb)->saddr, skb->dev, pref);
1206                 if (!rt) {
1207                         ND_PRINTK(0, err,
1208                                   "RA: %s failed to add default route\n",
1209                                   __func__);
1210                         return;
1211                 }
1212 
1213                 neigh = dst_neigh_lookup(&rt->dst, &ipv6_hdr(skb)->saddr);
1214                 if (!neigh) {
1215                         ND_PRINTK(0, err,
1216                                   "RA: %s got default router without neighbour\n",
1217                                   __func__);
1218                         ip6_rt_put(rt);
1219                         return;
1220                 }
1221                 neigh->flags |= NTF_ROUTER;
1222         } else if (rt) {
1223                 rt->rt6i_flags = (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
1224         }
1225 
1226         if (rt)
1227                 rt6_set_expires(rt, jiffies + (HZ * lifetime));
1228         if (in6_dev->cnf.accept_ra_min_hop_limit < 256 &&
1229             ra_msg->icmph.icmp6_hop_limit) {
1230                 if (in6_dev->cnf.accept_ra_min_hop_limit <= ra_msg->icmph.icmp6_hop_limit) {
1231                         in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
1232                         if (rt)
1233                                 dst_metric_set(&rt->dst, RTAX_HOPLIMIT,
1234                                                ra_msg->icmph.icmp6_hop_limit);
1235                 } else {
1236                         ND_PRINTK(2, warn, "RA: Got route advertisement with lower hop_limit than minimum\n");
1237                 }
1238         }
1239 
1240 skip_defrtr:
1241 
1242         /*
1243          *      Update Reachable Time and Retrans Timer
1244          */
1245 
1246         if (in6_dev->nd_parms) {
1247                 unsigned long rtime = ntohl(ra_msg->retrans_timer);
1248 
1249                 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/HZ) {
1250                         rtime = (rtime*HZ)/1000;
1251                         if (rtime < HZ/10)
1252                                 rtime = HZ/10;
1253                         NEIGH_VAR_SET(in6_dev->nd_parms, RETRANS_TIME, rtime);
1254                         in6_dev->tstamp = jiffies;
1255                         inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1256                 }
1257 
1258                 rtime = ntohl(ra_msg->reachable_time);
1259                 if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/(3*HZ)) {
1260                         rtime = (rtime*HZ)/1000;
1261 
1262                         if (rtime < HZ/10)
1263                                 rtime = HZ/10;
1264 
1265                         if (rtime != NEIGH_VAR(in6_dev->nd_parms, BASE_REACHABLE_TIME)) {
1266                                 NEIGH_VAR_SET(in6_dev->nd_parms,
1267                                               BASE_REACHABLE_TIME, rtime);
1268                                 NEIGH_VAR_SET(in6_dev->nd_parms,
1269                                               GC_STALETIME, 3 * rtime);
1270                                 in6_dev->nd_parms->reachable_time = neigh_rand_reach_time(rtime);
1271                                 in6_dev->tstamp = jiffies;
1272                                 inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
1273                         }
1274                 }
1275         }
1276 
1277 skip_linkparms:
1278 
1279         /*
1280          *      Process options.
1281          */
1282 
1283         if (!neigh)
1284                 neigh = __neigh_lookup(&nd_tbl, &ipv6_hdr(skb)->saddr,
1285                                        skb->dev, 1);
1286         if (neigh) {
1287                 u8 *lladdr = NULL;
1288                 if (ndopts.nd_opts_src_lladdr) {
1289                         lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr,
1290                                                      skb->dev);
1291                         if (!lladdr) {
1292                                 ND_PRINTK(2, warn,
1293                                           "RA: invalid link-layer address length\n");
1294                                 goto out;
1295                         }
1296                 }
1297                 neigh_update(neigh, lladdr, NUD_STALE,
1298                              NEIGH_UPDATE_F_WEAK_OVERRIDE|
1299                              NEIGH_UPDATE_F_OVERRIDE|
1300                              NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
1301                              NEIGH_UPDATE_F_ISROUTER);
1302         }
1303 
1304         if (!ipv6_accept_ra(in6_dev)) {
1305                 ND_PRINTK(2, info,
1306                           "RA: %s, accept_ra is false for dev: %s\n",
1307                           __func__, skb->dev->name);
1308                 goto out;
1309         }
1310 
1311 #ifdef CONFIG_IPV6_ROUTE_INFO
1312         if (!in6_dev->cnf.accept_ra_from_local &&
1313             ipv6_chk_addr(dev_net(in6_dev->dev), &ipv6_hdr(skb)->saddr,
1314                           NULL, 0)) {
1315                 ND_PRINTK(2, info,
1316                           "RA from local address detected on dev: %s: router info ignored.\n",
1317                           skb->dev->name);
1318                 goto skip_routeinfo;
1319         }
1320 
1321         if (in6_dev->cnf.accept_ra_rtr_pref && ndopts.nd_opts_ri) {
1322                 struct nd_opt_hdr *p;
1323                 for (p = ndopts.nd_opts_ri;
1324                      p;
1325                      p = ndisc_next_option(p, ndopts.nd_opts_ri_end)) {
1326                         struct route_info *ri = (struct route_info *)p;
1327 #ifdef CONFIG_IPV6_NDISC_NODETYPE
1328                         if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT &&
1329                             ri->prefix_len == 0)
1330                                 continue;
1331 #endif
1332                         if (ri->prefix_len == 0 &&
1333                             !in6_dev->cnf.accept_ra_defrtr)
1334                                 continue;
1335                         if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen)
1336                                 continue;
1337                         rt6_route_rcv(skb->dev, (u8 *)p, (p->nd_opt_len) << 3,
1338                                       &ipv6_hdr(skb)->saddr);
1339                 }
1340         }
1341 
1342 skip_routeinfo:
1343 #endif
1344 
1345 #ifdef CONFIG_IPV6_NDISC_NODETYPE
1346         /* skip link-specific ndopts from interior routers */
1347         if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT) {
1348                 ND_PRINTK(2, info,
1349                           "RA: %s, nodetype is NODEFAULT (interior routes), dev: %s\n",
1350                           __func__, skb->dev->name);
1351                 goto out;
1352         }
1353 #endif
1354 
1355         if (in6_dev->cnf.accept_ra_pinfo && ndopts.nd_opts_pi) {
1356                 struct nd_opt_hdr *p;
1357                 for (p = ndopts.nd_opts_pi;
1358                      p;
1359                      p = ndisc_next_option(p, ndopts.nd_opts_pi_end)) {
1360                         addrconf_prefix_rcv(skb->dev, (u8 *)p,
1361                                             (p->nd_opt_len) << 3,
1362                                             ndopts.nd_opts_src_lladdr != NULL);
1363                 }
1364         }
1365 
1366         if (ndopts.nd_opts_mtu && in6_dev->cnf.accept_ra_mtu) {
1367                 __be32 n;
1368                 u32 mtu;
1369 
1370                 memcpy(&n, ((u8 *)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
1371                 mtu = ntohl(n);
1372 
1373                 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
1374                         ND_PRINTK(2, warn, "RA: invalid mtu: %d\n", mtu);
1375                 } else if (in6_dev->cnf.mtu6 != mtu) {
1376                         in6_dev->cnf.mtu6 = mtu;
1377 
1378                         if (rt)
1379                                 dst_metric_set(&rt->dst, RTAX_MTU, mtu);
1380 
1381                         rt6_mtu_change(skb->dev, mtu);
1382                 }
1383         }
1384 
1385         if (ndopts.nd_useropts) {
1386                 struct nd_opt_hdr *p;
1387                 for (p = ndopts.nd_useropts;
1388                      p;
1389                      p = ndisc_next_useropt(p, ndopts.nd_useropts_end)) {
1390                         ndisc_ra_useropt(skb, p);
1391                 }
1392         }
1393 
1394         if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) {
1395                 ND_PRINTK(2, warn, "RA: invalid RA options\n");
1396         }
1397 out:
1398         ip6_rt_put(rt);
1399         if (neigh)
1400                 neigh_release(neigh);
1401 }
1402 
1403 static void ndisc_redirect_rcv(struct sk_buff *skb)
1404 {
1405         u8 *hdr;
1406         struct ndisc_options ndopts;
1407         struct rd_msg *msg = (struct rd_msg *)skb_transport_header(skb);
1408         u32 ndoptlen = skb_tail_pointer(skb) - (skb_transport_header(skb) +
1409                                     offsetof(struct rd_msg, opt));
1410 
1411 #ifdef CONFIG_IPV6_NDISC_NODETYPE
1412         switch (skb->ndisc_nodetype) {
1413         case NDISC_NODETYPE_HOST:
1414         case NDISC_NODETYPE_NODEFAULT:
1415                 ND_PRINTK(2, warn,
1416                           "Redirect: from host or unauthorized router\n");
1417                 return;
1418         }
1419 #endif
1420 
1421         if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) {
1422                 ND_PRINTK(2, warn,
1423                           "Redirect: source address is not link-local\n");
1424                 return;
1425         }
1426 
1427         if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts))
1428                 return;
1429 
1430         if (!ndopts.nd_opts_rh) {
1431                 ip6_redirect_no_header(skb, dev_net(skb->dev),
1432                                         skb->dev->ifindex, 0);
1433                 return;
1434         }
1435 
1436         hdr = (u8 *)ndopts.nd_opts_rh;
1437         hdr += 8;
1438         if (!pskb_pull(skb, hdr - skb_transport_header(skb)))
1439                 return;
1440 
1441         icmpv6_notify(skb, NDISC_REDIRECT, 0, 0);
1442 }
1443 
1444 static void ndisc_fill_redirect_hdr_option(struct sk_buff *skb,
1445                                            struct sk_buff *orig_skb,
1446                                            int rd_len)
1447 {
1448         u8 *opt = skb_put(skb, rd_len);
1449 
1450         memset(opt, 0, 8);
1451         *(opt++) = ND_OPT_REDIRECT_HDR;
1452         *(opt++) = (rd_len >> 3);
1453         opt += 6;
1454 
1455         skb_copy_bits(orig_skb, skb_network_offset(orig_skb), opt,
1456                       rd_len - 8);
1457 }
1458 
1459 void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
1460 {
1461         struct net_device *dev = skb->dev;
1462         struct net *net = dev_net(dev);
1463         struct sock *sk = net->ipv6.ndisc_sk;
1464         int optlen = 0;
1465         struct inet_peer *peer;
1466         struct sk_buff *buff;
1467         struct rd_msg *msg;
1468         struct in6_addr saddr_buf;
1469         struct rt6_info *rt;
1470         struct dst_entry *dst;
1471         struct flowi6 fl6;
1472         int rd_len;
1473         u8 ha_buf[MAX_ADDR_LEN], *ha = NULL;
1474         bool ret;
1475 
1476         if (ipv6_get_lladdr(dev, &saddr_buf, IFA_F_TENTATIVE)) {
1477                 ND_PRINTK(2, warn, "Redirect: no link-local address on %s\n",
1478                           dev->name);
1479                 return;
1480         }
1481 
1482         if (!ipv6_addr_equal(&ipv6_hdr(skb)->daddr, target) &&
1483             ipv6_addr_type(target) != (IPV6_ADDR_UNICAST|IPV6_ADDR_LINKLOCAL)) {
1484                 ND_PRINTK(2, warn,
1485                           "Redirect: target address is not link-local unicast\n");
1486                 return;
1487         }
1488 
1489         icmpv6_flow_init(sk, &fl6, NDISC_REDIRECT,
1490                          &saddr_buf, &ipv6_hdr(skb)->saddr, dev->ifindex);
1491 
1492         dst = ip6_route_output(net, NULL, &fl6);
1493         if (dst->error) {
1494                 dst_release(dst);
1495                 return;
1496         }
1497         dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
1498         if (IS_ERR(dst))
1499                 return;
1500 
1501         rt = (struct rt6_info *) dst;
1502 
1503         if (rt->rt6i_flags & RTF_GATEWAY) {
1504                 ND_PRINTK(2, warn,
1505                           "Redirect: destination is not a neighbour\n");
1506                 goto release;
1507         }
1508         peer = inet_getpeer_v6(net->ipv6.peers, &rt->rt6i_dst.addr, 1);
1509         ret = inet_peer_xrlim_allow(peer, 1*HZ);
1510         if (peer)
1511                 inet_putpeer(peer);
1512         if (!ret)
1513                 goto release;
1514 
1515         if (dev->addr_len) {
1516                 struct neighbour *neigh = dst_neigh_lookup(skb_dst(skb), target);
1517                 if (!neigh) {
1518                         ND_PRINTK(2, warn,
1519                                   "Redirect: no neigh for target address\n");
1520                         goto release;
1521                 }
1522 
1523                 read_lock_bh(&neigh->lock);
1524                 if (neigh->nud_state & NUD_VALID) {
1525                         memcpy(ha_buf, neigh->ha, dev->addr_len);
1526                         read_unlock_bh(&neigh->lock);
1527                         ha = ha_buf;
1528                         optlen += ndisc_opt_addr_space(dev);
1529                 } else
1530                         read_unlock_bh(&neigh->lock);
1531 
1532                 neigh_release(neigh);
1533         }
1534 
1535         rd_len = min_t(unsigned int,
1536                        IPV6_MIN_MTU - sizeof(struct ipv6hdr) - sizeof(*msg) - optlen,
1537                        skb->len + 8);
1538         rd_len &= ~0x7;
1539         optlen += rd_len;
1540 
1541         buff = ndisc_alloc_skb(dev, sizeof(*msg) + optlen);
1542         if (!buff)
1543                 goto release;
1544 
1545         msg = (struct rd_msg *)skb_put(buff, sizeof(*msg));
1546         *msg = (struct rd_msg) {
1547                 .icmph = {
1548                         .icmp6_type = NDISC_REDIRECT,
1549                 },
1550                 .target = *target,
1551                 .dest = ipv6_hdr(skb)->daddr,
1552         };
1553 
1554         /*
1555          *      include target_address option
1556          */
1557 
1558         if (ha)
1559                 ndisc_fill_addr_option(buff, ND_OPT_TARGET_LL_ADDR, ha);
1560 
1561         /*
1562          *      build redirect option and copy skb over to the new packet.
1563          */
1564 
1565         if (rd_len)
1566                 ndisc_fill_redirect_hdr_option(buff, skb, rd_len);
1567 
1568         skb_dst_set(buff, dst);
1569         ndisc_send_skb(buff, &ipv6_hdr(skb)->saddr, &saddr_buf);
1570         return;
1571 
1572 release:
1573         dst_release(dst);
1574 }
1575 
1576 static void pndisc_redo(struct sk_buff *skb)
1577 {
1578         ndisc_recv_ns(skb);
1579         kfree_skb(skb);
1580 }
1581 
1582 static bool ndisc_suppress_frag_ndisc(struct sk_buff *skb)
1583 {
1584         struct inet6_dev *idev = __in6_dev_get(skb->dev);
1585 
1586         if (!idev)
1587                 return true;
1588         if (IP6CB(skb)->flags & IP6SKB_FRAGMENTED &&
1589             idev->cnf.suppress_frag_ndisc) {
1590                 net_warn_ratelimited("Received fragmented ndisc packet. Carefully consider disabling suppress_frag_ndisc.\n");
1591                 return true;
1592         }
1593         return false;
1594 }
1595 
1596 int ndisc_rcv(struct sk_buff *skb)
1597 {
1598         struct nd_msg *msg;
1599 
1600         if (ndisc_suppress_frag_ndisc(skb))
1601                 return 0;
1602 
1603         if (skb_linearize(skb))
1604                 return 0;
1605 
1606         msg = (struct nd_msg *)skb_transport_header(skb);
1607 
1608         __skb_push(skb, skb->data - skb_transport_header(skb));
1609 
1610         if (ipv6_hdr(skb)->hop_limit != 255) {
1611                 ND_PRINTK(2, warn, "NDISC: invalid hop-limit: %d\n",
1612                           ipv6_hdr(skb)->hop_limit);
1613                 return 0;
1614         }
1615 
1616         if (msg->icmph.icmp6_code != 0) {
1617                 ND_PRINTK(2, warn, "NDISC: invalid ICMPv6 code: %d\n",
1618                           msg->icmph.icmp6_code);
1619                 return 0;
1620         }
1621 
1622         memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));
1623 
1624         switch (msg->icmph.icmp6_type) {
1625         case NDISC_NEIGHBOUR_SOLICITATION:
1626                 ndisc_recv_ns(skb);
1627                 break;
1628 
1629         case NDISC_NEIGHBOUR_ADVERTISEMENT:
1630                 ndisc_recv_na(skb);
1631                 break;
1632 
1633         case NDISC_ROUTER_SOLICITATION:
1634                 ndisc_recv_rs(skb);
1635                 break;
1636 
1637         case NDISC_ROUTER_ADVERTISEMENT:
1638                 ndisc_router_discovery(skb);
1639                 break;
1640 
1641         case NDISC_REDIRECT:
1642                 ndisc_redirect_rcv(skb);
1643                 break;
1644         }
1645 
1646         return 0;
1647 }
1648 
1649 static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
1650 {
1651         struct net_device *dev = netdev_notifier_info_to_dev(ptr);
1652         struct net *net = dev_net(dev);
1653         struct inet6_dev *idev;
1654 
1655         switch (event) {
1656         case NETDEV_CHANGEADDR:
1657                 neigh_changeaddr(&nd_tbl, dev);
1658                 fib6_run_gc(0, net, false);
1659                 /* fallthrough */
1660         case NETDEV_UP:
1661                 idev = in6_dev_get(dev);
1662                 if (!idev)
1663                         break;
1664                 if (idev->cnf.ndisc_notify)
1665                         ndisc_send_unsol_na(dev);
1666                 in6_dev_put(idev);
1667                 break;
1668         case NETDEV_DOWN:
1669                 neigh_ifdown(&nd_tbl, dev);
1670                 fib6_run_gc(0, net, false);
1671                 break;
1672         case NETDEV_NOTIFY_PEERS:
1673                 ndisc_send_unsol_na(dev);
1674                 break;
1675         default:
1676                 break;
1677         }
1678 
1679         return NOTIFY_DONE;
1680 }
1681 
1682 static struct notifier_block ndisc_netdev_notifier = {
1683         .notifier_call = ndisc_netdev_event,
1684 };
1685 
1686 #ifdef CONFIG_SYSCTL
1687 static void ndisc_warn_deprecated_sysctl(struct ctl_table *ctl,
1688                                          const char *func, const char *dev_name)
1689 {
1690         static char warncomm[TASK_COMM_LEN];
1691         static int warned;
1692         if (strcmp(warncomm, current->comm) && warned < 5) {
1693                 strcpy(warncomm, current->comm);
1694                 pr_warn("process `%s' is using deprecated sysctl (%s) net.ipv6.neigh.%s.%s - use net.ipv6.neigh.%s.%s_ms instead\n",
1695                         warncomm, func,
1696                         dev_name, ctl->procname,
1697                         dev_name, ctl->procname);
1698                 warned++;
1699         }
1700 }
1701 
1702 int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
1703 {
1704         struct net_device *dev = ctl->extra1;
1705         struct inet6_dev *idev;
1706         int ret;
1707 
1708         if ((strcmp(ctl->procname, "retrans_time") == 0) ||
1709             (strcmp(ctl->procname, "base_reachable_time") == 0))
1710                 ndisc_warn_deprecated_sysctl(ctl, "syscall", dev ? dev->name : "default");
1711 
1712         if (strcmp(ctl->procname, "retrans_time") == 0)
1713                 ret = neigh_proc_dointvec(ctl, write, buffer, lenp, ppos);
1714 
1715         else if (strcmp(ctl->procname, "base_reachable_time") == 0)
1716                 ret = neigh_proc_dointvec_jiffies(ctl, write,
1717                                                   buffer, lenp, ppos);
1718 
1719         else if ((strcmp(ctl->procname, "retrans_time_ms") == 0) ||
1720                  (strcmp(ctl->procname, "base_reachable_time_ms") == 0))
1721                 ret = neigh_proc_dointvec_ms_jiffies(ctl, write,
1722                                                      buffer, lenp, ppos);
1723         else
1724                 ret = -1;
1725 
1726         if (write && ret == 0 && dev && (idev = in6_dev_get(dev)) != NULL) {
1727                 if (ctl->data == &NEIGH_VAR(idev->nd_parms, BASE_REACHABLE_TIME))
1728                         idev->nd_parms->reachable_time =
1729                                         neigh_rand_reach_time(NEIGH_VAR(idev->nd_parms, BASE_REACHABLE_TIME));
1730                 idev->tstamp = jiffies;
1731                 inet6_ifinfo_notify(RTM_NEWLINK, idev);
1732                 in6_dev_put(idev);
1733         }
1734         return ret;
1735 }
1736 
1737 
1738 #endif
1739 
1740 static int __net_init ndisc_net_init(struct net *net)
1741 {
1742         struct ipv6_pinfo *np;
1743         struct sock *sk;
1744         int err;
1745 
1746         err = inet_ctl_sock_create(&sk, PF_INET6,
1747                                    SOCK_RAW, IPPROTO_ICMPV6, net);
1748         if (err < 0) {
1749                 ND_PRINTK(0, err,
1750                           "NDISC: Failed to initialize the control socket (err %d)\n",
1751                           err);
1752                 return err;
1753         }
1754 
1755         net->ipv6.ndisc_sk = sk;
1756 
1757         np = inet6_sk(sk);
1758         np->hop_limit = 255;
1759         /* Do not loopback ndisc messages */
1760         np->mc_loop = 0;
1761 
1762         return 0;
1763 }
1764 
1765 static void __net_exit ndisc_net_exit(struct net *net)
1766 {
1767         inet_ctl_sock_destroy(net->ipv6.ndisc_sk);
1768 }
1769 
1770 static struct pernet_operations ndisc_net_ops = {
1771         .init = ndisc_net_init,
1772         .exit = ndisc_net_exit,
1773 };
1774 
1775 int __init ndisc_init(void)
1776 {
1777         int err;
1778 
1779         err = register_pernet_subsys(&ndisc_net_ops);
1780         if (err)
1781                 return err;
1782         /*
1783          * Initialize the neighbour table
1784          */
1785         neigh_table_init(NEIGH_ND_TABLE, &nd_tbl);
1786 
1787 #ifdef CONFIG_SYSCTL
1788         err = neigh_sysctl_register(NULL, &nd_tbl.parms,
1789                                     ndisc_ifinfo_sysctl_change);
1790         if (err)
1791                 goto out_unregister_pernet;
1792 out:
1793 #endif
1794         return err;
1795 
1796 #ifdef CONFIG_SYSCTL
1797 out_unregister_pernet:
1798         unregister_pernet_subsys(&ndisc_net_ops);
1799         goto out;
1800 #endif
1801 }
1802 
1803 int __init ndisc_late_init(void)
1804 {
1805         return register_netdevice_notifier(&ndisc_netdev_notifier);
1806 }
1807 
1808 void ndisc_late_cleanup(void)
1809 {
1810         unregister_netdevice_notifier(&ndisc_netdev_notifier);
1811 }
1812 
1813 void ndisc_cleanup(void)
1814 {
1815 #ifdef CONFIG_SYSCTL
1816         neigh_sysctl_unregister(&nd_tbl.parms);
1817 #endif
1818         neigh_table_clear(NEIGH_ND_TABLE, &nd_tbl);
1819         unregister_pernet_subsys(&ndisc_net_ops);
1820 }
1821 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp