aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c177
1 files changed, 162 insertions, 15 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 0424e4e27414..fab23db8ee73 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -81,6 +81,7 @@
81#include <net/pkt_sched.h> 81#include <net/pkt_sched.h>
82#include <linux/if_tunnel.h> 82#include <linux/if_tunnel.h>
83#include <linux/rtnetlink.h> 83#include <linux/rtnetlink.h>
84#include <linux/netconf.h>
84 85
85#ifdef CONFIG_IPV6_PRIVACY 86#ifdef CONFIG_IPV6_PRIVACY
86#include <linux/random.h> 87#include <linux/random.h>
@@ -401,7 +402,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
401 if (dev->flags & (IFF_NOARP | IFF_LOOPBACK)) 402 if (dev->flags & (IFF_NOARP | IFF_LOOPBACK))
402 ndev->cnf.accept_dad = -1; 403 ndev->cnf.accept_dad = -1;
403 404
404#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) 405#if IS_ENABLED(CONFIG_IPV6_SIT)
405 if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) { 406 if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) {
406 pr_info("%s: Disabled Multicast RS\n", dev->name); 407 pr_info("%s: Disabled Multicast RS\n", dev->name);
407 ndev->cnf.rtr_solicits = 0; 408 ndev->cnf.rtr_solicits = 0;
@@ -460,6 +461,141 @@ static struct inet6_dev *ipv6_find_idev(struct net_device *dev)
460 return idev; 461 return idev;
461} 462}
462 463
464static int inet6_netconf_msgsize_devconf(int type)
465{
466 int size = NLMSG_ALIGN(sizeof(struct netconfmsg))
467 + nla_total_size(4); /* NETCONFA_IFINDEX */
468
469 /* type -1 is used for ALL */
470 if (type == -1 || type == NETCONFA_FORWARDING)
471 size += nla_total_size(4);
472
473 return size;
474}
475
476static int inet6_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
477 struct ipv6_devconf *devconf, u32 portid,
478 u32 seq, int event, unsigned int flags,
479 int type)
480{
481 struct nlmsghdr *nlh;
482 struct netconfmsg *ncm;
483
484 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct netconfmsg),
485 flags);
486 if (nlh == NULL)
487 return -EMSGSIZE;
488
489 ncm = nlmsg_data(nlh);
490 ncm->ncm_family = AF_INET6;
491
492 if (nla_put_s32(skb, NETCONFA_IFINDEX, ifindex) < 0)
493 goto nla_put_failure;
494
495 /* type -1 is used for ALL */
496 if ((type == -1 || type == NETCONFA_FORWARDING) &&
497 nla_put_s32(skb, NETCONFA_FORWARDING, devconf->forwarding) < 0)
498 goto nla_put_failure;
499
500 return nlmsg_end(skb, nlh);
501
502nla_put_failure:
503 nlmsg_cancel(skb, nlh);
504 return -EMSGSIZE;
505}
506
507static void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex,
508 struct ipv6_devconf *devconf)
509{
510 struct sk_buff *skb;
511 int err = -ENOBUFS;
512
513 skb = nlmsg_new(inet6_netconf_msgsize_devconf(type), GFP_ATOMIC);
514 if (skb == NULL)
515 goto errout;
516
517 err = inet6_netconf_fill_devconf(skb, ifindex, devconf, 0, 0,
518 RTM_NEWNETCONF, 0, type);
519 if (err < 0) {
520 /* -EMSGSIZE implies BUG in inet6_netconf_msgsize_devconf() */
521 WARN_ON(err == -EMSGSIZE);
522 kfree_skb(skb);
523 goto errout;
524 }
525 rtnl_notify(skb, net, 0, RTNLGRP_IPV6_NETCONF, NULL, GFP_ATOMIC);
526 return;
527errout:
528 if (err < 0)
529 rtnl_set_sk_err(net, RTNLGRP_IPV6_NETCONF, err);
530}
531
532static const struct nla_policy devconf_ipv6_policy[NETCONFA_MAX+1] = {
533 [NETCONFA_IFINDEX] = { .len = sizeof(int) },
534 [NETCONFA_FORWARDING] = { .len = sizeof(int) },
535};
536
537static int inet6_netconf_get_devconf(struct sk_buff *in_skb,
538 struct nlmsghdr *nlh,
539 void *arg)
540{
541 struct net *net = sock_net(in_skb->sk);
542 struct nlattr *tb[NETCONFA_MAX+1];
543 struct netconfmsg *ncm;
544 struct sk_buff *skb;
545 struct ipv6_devconf *devconf;
546 struct inet6_dev *in6_dev;
547 struct net_device *dev;
548 int ifindex;
549 int err;
550
551 err = nlmsg_parse(nlh, sizeof(*ncm), tb, NETCONFA_MAX,
552 devconf_ipv6_policy);
553 if (err < 0)
554 goto errout;
555
556 err = EINVAL;
557 if (!tb[NETCONFA_IFINDEX])
558 goto errout;
559
560 ifindex = nla_get_s32(tb[NETCONFA_IFINDEX]);
561 switch (ifindex) {
562 case NETCONFA_IFINDEX_ALL:
563 devconf = net->ipv6.devconf_all;
564 break;
565 case NETCONFA_IFINDEX_DEFAULT:
566 devconf = net->ipv6.devconf_dflt;
567 break;
568 default:
569 dev = __dev_get_by_index(net, ifindex);
570 if (dev == NULL)
571 goto errout;
572 in6_dev = __in6_dev_get(dev);
573 if (in6_dev == NULL)
574 goto errout;
575 devconf = &in6_dev->cnf;
576 break;
577 }
578
579 err = -ENOBUFS;
580 skb = nlmsg_new(inet6_netconf_msgsize_devconf(-1), GFP_ATOMIC);
581 if (skb == NULL)
582 goto errout;
583
584 err = inet6_netconf_fill_devconf(skb, ifindex, devconf,
585 NETLINK_CB(in_skb).portid,
586 nlh->nlmsg_seq, RTM_NEWNETCONF, 0,
587 -1);
588 if (err < 0) {
589 /* -EMSGSIZE implies BUG in inet6_netconf_msgsize_devconf() */
590 WARN_ON(err == -EMSGSIZE);
591 kfree_skb(skb);
592 goto errout;
593 }
594 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
595errout:
596 return err;
597}
598
463#ifdef CONFIG_SYSCTL 599#ifdef CONFIG_SYSCTL
464static void dev_forward_change(struct inet6_dev *idev) 600static void dev_forward_change(struct inet6_dev *idev)
465{ 601{
@@ -471,7 +607,7 @@ static void dev_forward_change(struct inet6_dev *idev)
471 dev = idev->dev; 607 dev = idev->dev;
472 if (idev->cnf.forwarding) 608 if (idev->cnf.forwarding)
473 dev_disable_lro(dev); 609 dev_disable_lro(dev);
474 if (dev && (dev->flags & IFF_MULTICAST)) { 610 if (dev->flags & IFF_MULTICAST) {
475 if (idev->cnf.forwarding) 611 if (idev->cnf.forwarding)
476 ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters); 612 ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters);
477 else 613 else
@@ -486,6 +622,8 @@ static void dev_forward_change(struct inet6_dev *idev)
486 else 622 else
487 addrconf_leave_anycast(ifa); 623 addrconf_leave_anycast(ifa);
488 } 624 }
625 inet6_netconf_notify_devconf(dev_net(dev), NETCONFA_FORWARDING,
626 dev->ifindex, &idev->cnf);
489} 627}
490 628
491 629
@@ -518,6 +656,10 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf)
518 *p = newf; 656 *p = newf;
519 657
520 if (p == &net->ipv6.devconf_dflt->forwarding) { 658 if (p == &net->ipv6.devconf_dflt->forwarding) {
659 if ((!newf) ^ (!old))
660 inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING,
661 NETCONFA_IFINDEX_DEFAULT,
662 net->ipv6.devconf_dflt);
521 rtnl_unlock(); 663 rtnl_unlock();
522 return 0; 664 return 0;
523 } 665 }
@@ -525,6 +667,10 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf)
525 if (p == &net->ipv6.devconf_all->forwarding) { 667 if (p == &net->ipv6.devconf_all->forwarding) {
526 net->ipv6.devconf_dflt->forwarding = newf; 668 net->ipv6.devconf_dflt->forwarding = newf;
527 addrconf_forward_change(net, newf); 669 addrconf_forward_change(net, newf);
670 if ((!newf) ^ (!old))
671 inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING,
672 NETCONFA_IFINDEX_ALL,
673 net->ipv6.devconf_all);
528 } else if ((!newf) ^ (!old)) 674 } else if ((!newf) ^ (!old))
529 dev_forward_change((struct inet6_dev *)table->extra1); 675 dev_forward_change((struct inet6_dev *)table->extra1);
530 rtnl_unlock(); 676 rtnl_unlock();
@@ -553,7 +699,7 @@ void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)
553 pr_warn("Freeing alive inet6 address %p\n", ifp); 699 pr_warn("Freeing alive inet6 address %p\n", ifp);
554 return; 700 return;
555 } 701 }
556 dst_release(&ifp->rt->dst); 702 ip6_rt_put(ifp->rt);
557 703
558 kfree_rcu(ifp, rcu); 704 kfree_rcu(ifp, rcu);
559} 705}
@@ -805,7 +951,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
805 rt6_set_expires(rt, expires); 951 rt6_set_expires(rt, expires);
806 } 952 }
807 } 953 }
808 dst_release(&rt->dst); 954 ip6_rt_put(rt);
809 } 955 }
810 956
811 /* clean up prefsrc entries */ 957 /* clean up prefsrc entries */
@@ -1692,7 +1838,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
1692 This thing is done here expecting that the whole 1838 This thing is done here expecting that the whole
1693 class of non-broadcast devices need not cloning. 1839 class of non-broadcast devices need not cloning.
1694 */ 1840 */
1695#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) 1841#if IS_ENABLED(CONFIG_IPV6_SIT)
1696 if (dev->type == ARPHRD_SIT && (dev->flags & IFF_POINTOPOINT)) 1842 if (dev->type == ARPHRD_SIT && (dev->flags & IFF_POINTOPOINT))
1697 cfg.fc_flags |= RTF_NONEXTHOP; 1843 cfg.fc_flags |= RTF_NONEXTHOP;
1698#endif 1844#endif
@@ -1752,7 +1898,7 @@ static void addrconf_add_mroute(struct net_device *dev)
1752 ip6_route_add(&cfg); 1898 ip6_route_add(&cfg);
1753} 1899}
1754 1900
1755#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) 1901#if IS_ENABLED(CONFIG_IPV6_SIT)
1756static void sit_route_add(struct net_device *dev) 1902static void sit_route_add(struct net_device *dev)
1757{ 1903{
1758 struct fib6_config cfg = { 1904 struct fib6_config cfg = {
@@ -1881,8 +2027,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)
1881 addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len, 2027 addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len,
1882 dev, expires, flags); 2028 dev, expires, flags);
1883 } 2029 }
1884 if (rt) 2030 ip6_rt_put(rt);
1885 dst_release(&rt->dst);
1886 } 2031 }
1887 2032
1888 /* Try to figure out our local address for this prefix */ 2033 /* Try to figure out our local address for this prefix */
@@ -2104,7 +2249,7 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg)
2104 if (dev == NULL) 2249 if (dev == NULL)
2105 goto err_exit; 2250 goto err_exit;
2106 2251
2107#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) 2252#if IS_ENABLED(CONFIG_IPV6_SIT)
2108 if (dev->type == ARPHRD_SIT) { 2253 if (dev->type == ARPHRD_SIT) {
2109 const struct net_device_ops *ops = dev->netdev_ops; 2254 const struct net_device_ops *ops = dev->netdev_ops;
2110 struct ifreq ifr; 2255 struct ifreq ifr;
@@ -2315,7 +2460,7 @@ static void add_addr(struct inet6_dev *idev, const struct in6_addr *addr,
2315 } 2460 }
2316} 2461}
2317 2462
2318#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) 2463#if IS_ENABLED(CONFIG_IPV6_SIT)
2319static void sit_add_v4_addrs(struct inet6_dev *idev) 2464static void sit_add_v4_addrs(struct inet6_dev *idev)
2320{ 2465{
2321 struct in6_addr addr; 2466 struct in6_addr addr;
@@ -2434,7 +2579,7 @@ static void addrconf_dev_config(struct net_device *dev)
2434 addrconf_add_linklocal(idev, &addr); 2579 addrconf_add_linklocal(idev, &addr);
2435} 2580}
2436 2581
2437#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) 2582#if IS_ENABLED(CONFIG_IPV6_SIT)
2438static void addrconf_sit_config(struct net_device *dev) 2583static void addrconf_sit_config(struct net_device *dev)
2439{ 2584{
2440 struct inet6_dev *idev; 2585 struct inet6_dev *idev;
@@ -2471,7 +2616,7 @@ static void addrconf_sit_config(struct net_device *dev)
2471} 2616}
2472#endif 2617#endif
2473 2618
2474#if defined(CONFIG_NET_IPGRE) || defined(CONFIG_NET_IPGRE_MODULE) 2619#if IS_ENABLED(CONFIG_NET_IPGRE)
2475static void addrconf_gre_config(struct net_device *dev) 2620static void addrconf_gre_config(struct net_device *dev)
2476{ 2621{
2477 struct inet6_dev *idev; 2622 struct inet6_dev *idev;
@@ -2601,12 +2746,12 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
2601 } 2746 }
2602 2747
2603 switch (dev->type) { 2748 switch (dev->type) {
2604#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) 2749#if IS_ENABLED(CONFIG_IPV6_SIT)
2605 case ARPHRD_SIT: 2750 case ARPHRD_SIT:
2606 addrconf_sit_config(dev); 2751 addrconf_sit_config(dev);
2607 break; 2752 break;
2608#endif 2753#endif
2609#if defined(CONFIG_NET_IPGRE) || defined(CONFIG_NET_IPGRE_MODULE) 2754#if IS_ENABLED(CONFIG_NET_IPGRE)
2610 case ARPHRD_IPGRE: 2755 case ARPHRD_IPGRE:
2611 addrconf_gre_config(dev); 2756 addrconf_gre_config(dev);
2612 break; 2757 break;
@@ -3194,7 +3339,7 @@ void if6_proc_exit(void)
3194} 3339}
3195#endif /* CONFIG_PROC_FS */ 3340#endif /* CONFIG_PROC_FS */
3196 3341
3197#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) 3342#if IS_ENABLED(CONFIG_IPV6_MIP6)
3198/* Check if address is a home address configured on any interface. */ 3343/* Check if address is a home address configured on any interface. */
3199int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr) 3344int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr)
3200{ 3345{
@@ -4784,6 +4929,8 @@ int __init addrconf_init(void)
4784 inet6_dump_ifmcaddr, NULL); 4929 inet6_dump_ifmcaddr, NULL);
4785 __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL, 4930 __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL,
4786 inet6_dump_ifacaddr, NULL); 4931 inet6_dump_ifacaddr, NULL);
4932 __rtnl_register(PF_INET6, RTM_GETNETCONF, inet6_netconf_get_devconf,
4933 NULL, NULL);
4787 4934
4788 ipv6_addr_label_rtnl_register(); 4935 ipv6_addr_label_rtnl_register();
4789 4936