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

~ [ 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