addrconf.c (e0d81d92f7601c3dc63e5127bb77b6cd77f14a93) addrconf.c (dac9c9790e542777079999900594fd069ba10489)
1/*
2 * IPv6 Address [auto]configuration
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
8 *

--- 983 unchanged lines hidden (view full) ---

992 struct net *net = dev_net(idev->dev);
993 struct inet6_ifaddr *ifa = NULL;
994 struct fib6_info *f6i = NULL;
995 int err = 0;
996
997 if (addr_type == IPV6_ADDR_ANY ||
998 addr_type & IPV6_ADDR_MULTICAST ||
999 (!(idev->dev->flags & IFF_LOOPBACK) &&
1/*
2 * IPv6 Address [auto]configuration
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
8 *

--- 983 unchanged lines hidden (view full) ---

992 struct net *net = dev_net(idev->dev);
993 struct inet6_ifaddr *ifa = NULL;
994 struct fib6_info *f6i = NULL;
995 int err = 0;
996
997 if (addr_type == IPV6_ADDR_ANY ||
998 addr_type & IPV6_ADDR_MULTICAST ||
999 (!(idev->dev->flags & IFF_LOOPBACK) &&
1000 !netif_is_l3_master(idev->dev) &&
1000 addr_type & IPV6_ADDR_LOOPBACK))
1001 return ERR_PTR(-EADDRNOTAVAIL);
1002
1003 if (idev->dead) {
1004 err = -ENODEV; /*XXX*/
1005 goto out;
1006 }
1007

--- 3476 unchanged lines hidden (view full) ---

4484}
4485
4486static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = {
4487 [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) },
4488 [IFA_LOCAL] = { .len = sizeof(struct in6_addr) },
4489 [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) },
4490 [IFA_FLAGS] = { .len = sizeof(u32) },
4491 [IFA_RT_PRIORITY] = { .len = sizeof(u32) },
1001 addr_type & IPV6_ADDR_LOOPBACK))
1002 return ERR_PTR(-EADDRNOTAVAIL);
1003
1004 if (idev->dead) {
1005 err = -ENODEV; /*XXX*/
1006 goto out;
1007 }
1008

--- 3476 unchanged lines hidden (view full) ---

4485}
4486
4487static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = {
4488 [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) },
4489 [IFA_LOCAL] = { .len = sizeof(struct in6_addr) },
4490 [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) },
4491 [IFA_FLAGS] = { .len = sizeof(u32) },
4492 [IFA_RT_PRIORITY] = { .len = sizeof(u32) },
4493 [IFA_TARGET_NETNSID] = { .type = NLA_S32 },
4492};
4493
4494static int
4495inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh,
4496 struct netlink_ext_ack *extack)
4497{
4498 struct net *net = sock_net(skb->sk);
4499 struct ifaddrmsg *ifm;

--- 286 unchanged lines hidden (view full) ---

4786 return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
4787 + nla_total_size(16) /* IFA_LOCAL */
4788 + nla_total_size(16) /* IFA_ADDRESS */
4789 + nla_total_size(sizeof(struct ifa_cacheinfo))
4790 + nla_total_size(4) /* IFA_FLAGS */
4791 + nla_total_size(4) /* IFA_RT_PRIORITY */;
4792}
4793
4494};
4495
4496static int
4497inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh,
4498 struct netlink_ext_ack *extack)
4499{
4500 struct net *net = sock_net(skb->sk);
4501 struct ifaddrmsg *ifm;

--- 286 unchanged lines hidden (view full) ---

4788 return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
4789 + nla_total_size(16) /* IFA_LOCAL */
4790 + nla_total_size(16) /* IFA_ADDRESS */
4791 + nla_total_size(sizeof(struct ifa_cacheinfo))
4792 + nla_total_size(4) /* IFA_FLAGS */
4793 + nla_total_size(4) /* IFA_RT_PRIORITY */;
4794}
4795
4796struct inet6_fill_args {
4797 u32 portid;
4798 u32 seq;
4799 int event;
4800 unsigned int flags;
4801 int netnsid;
4802};
4803
4794static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
4804static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
4795 u32 portid, u32 seq, int event, unsigned int flags)
4805 struct inet6_fill_args *args)
4796{
4797 struct nlmsghdr *nlh;
4798 u32 preferred, valid;
4799
4806{
4807 struct nlmsghdr *nlh;
4808 u32 preferred, valid;
4809
4800 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
4810 nlh = nlmsg_put(skb, args->portid, args->seq, args->event,
4811 sizeof(struct ifaddrmsg), args->flags);
4801 if (!nlh)
4802 return -EMSGSIZE;
4803
4804 put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope),
4805 ifa->idev->dev->ifindex);
4806
4812 if (!nlh)
4813 return -EMSGSIZE;
4814
4815 put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope),
4816 ifa->idev->dev->ifindex);
4817
4818 if (args->netnsid >= 0 &&
4819 nla_put_s32(skb, IFA_TARGET_NETNSID, args->netnsid))
4820 goto error;
4821
4807 if (!((ifa->flags&IFA_F_PERMANENT) &&
4808 (ifa->prefered_lft == INFINITY_LIFE_TIME))) {
4809 preferred = ifa->prefered_lft;
4810 valid = ifa->valid_lft;
4811 if (preferred != INFINITY_LIFE_TIME) {
4812 long tval = (jiffies - ifa->tstamp)/HZ;
4813 if (preferred > tval)
4814 preferred -= tval;

--- 33 unchanged lines hidden (view full) ---

4848 return 0;
4849
4850error:
4851 nlmsg_cancel(skb, nlh);
4852 return -EMSGSIZE;
4853}
4854
4855static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
4822 if (!((ifa->flags&IFA_F_PERMANENT) &&
4823 (ifa->prefered_lft == INFINITY_LIFE_TIME))) {
4824 preferred = ifa->prefered_lft;
4825 valid = ifa->valid_lft;
4826 if (preferred != INFINITY_LIFE_TIME) {
4827 long tval = (jiffies - ifa->tstamp)/HZ;
4828 if (preferred > tval)
4829 preferred -= tval;

--- 33 unchanged lines hidden (view full) ---

4863 return 0;
4864
4865error:
4866 nlmsg_cancel(skb, nlh);
4867 return -EMSGSIZE;
4868}
4869
4870static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
4856 u32 portid, u32 seq, int event, u16 flags)
4871 struct inet6_fill_args *args)
4857{
4858 struct nlmsghdr *nlh;
4859 u8 scope = RT_SCOPE_UNIVERSE;
4860 int ifindex = ifmca->idev->dev->ifindex;
4861
4862 if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE)
4863 scope = RT_SCOPE_SITE;
4864
4872{
4873 struct nlmsghdr *nlh;
4874 u8 scope = RT_SCOPE_UNIVERSE;
4875 int ifindex = ifmca->idev->dev->ifindex;
4876
4877 if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE)
4878 scope = RT_SCOPE_SITE;
4879
4865 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
4880 nlh = nlmsg_put(skb, args->portid, args->seq, args->event,
4881 sizeof(struct ifaddrmsg), args->flags);
4866 if (!nlh)
4867 return -EMSGSIZE;
4868
4882 if (!nlh)
4883 return -EMSGSIZE;
4884
4885 if (args->netnsid >= 0 &&
4886 nla_put_s32(skb, IFA_TARGET_NETNSID, args->netnsid))
4887 return -EMSGSIZE;
4888
4869 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
4870 if (nla_put_in6_addr(skb, IFA_MULTICAST, &ifmca->mca_addr) < 0 ||
4871 put_cacheinfo(skb, ifmca->mca_cstamp, ifmca->mca_tstamp,
4872 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
4873 nlmsg_cancel(skb, nlh);
4874 return -EMSGSIZE;
4875 }
4876
4877 nlmsg_end(skb, nlh);
4878 return 0;
4879}
4880
4881static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
4889 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
4890 if (nla_put_in6_addr(skb, IFA_MULTICAST, &ifmca->mca_addr) < 0 ||
4891 put_cacheinfo(skb, ifmca->mca_cstamp, ifmca->mca_tstamp,
4892 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
4893 nlmsg_cancel(skb, nlh);
4894 return -EMSGSIZE;
4895 }
4896
4897 nlmsg_end(skb, nlh);
4898 return 0;
4899}
4900
4901static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
4882 u32 portid, u32 seq, int event, unsigned int flags)
4902 struct inet6_fill_args *args)
4883{
4884 struct net_device *dev = fib6_info_nh_dev(ifaca->aca_rt);
4885 int ifindex = dev ? dev->ifindex : 1;
4886 struct nlmsghdr *nlh;
4887 u8 scope = RT_SCOPE_UNIVERSE;
4888
4889 if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE)
4890 scope = RT_SCOPE_SITE;
4891
4903{
4904 struct net_device *dev = fib6_info_nh_dev(ifaca->aca_rt);
4905 int ifindex = dev ? dev->ifindex : 1;
4906 struct nlmsghdr *nlh;
4907 u8 scope = RT_SCOPE_UNIVERSE;
4908
4909 if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE)
4910 scope = RT_SCOPE_SITE;
4911
4892 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
4912 nlh = nlmsg_put(skb, args->portid, args->seq, args->event,
4913 sizeof(struct ifaddrmsg), args->flags);
4893 if (!nlh)
4894 return -EMSGSIZE;
4895
4914 if (!nlh)
4915 return -EMSGSIZE;
4916
4917 if (args->netnsid >= 0 &&
4918 nla_put_s32(skb, IFA_TARGET_NETNSID, args->netnsid))
4919 return -EMSGSIZE;
4920
4896 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
4897 if (nla_put_in6_addr(skb, IFA_ANYCAST, &ifaca->aca_addr) < 0 ||
4898 put_cacheinfo(skb, ifaca->aca_cstamp, ifaca->aca_tstamp,
4899 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
4900 nlmsg_cancel(skb, nlh);
4901 return -EMSGSIZE;
4902 }
4903

--- 5 unchanged lines hidden (view full) ---

4909 UNICAST_ADDR,
4910 MULTICAST_ADDR,
4911 ANYCAST_ADDR,
4912};
4913
4914/* called with rcu_read_lock() */
4915static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
4916 struct netlink_callback *cb, enum addr_type_t type,
4921 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
4922 if (nla_put_in6_addr(skb, IFA_ANYCAST, &ifaca->aca_addr) < 0 ||
4923 put_cacheinfo(skb, ifaca->aca_cstamp, ifaca->aca_tstamp,
4924 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
4925 nlmsg_cancel(skb, nlh);
4926 return -EMSGSIZE;
4927 }
4928

--- 5 unchanged lines hidden (view full) ---

4934 UNICAST_ADDR,
4935 MULTICAST_ADDR,
4936 ANYCAST_ADDR,
4937};
4938
4939/* called with rcu_read_lock() */
4940static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
4941 struct netlink_callback *cb, enum addr_type_t type,
4917 int s_ip_idx, int *p_ip_idx)
4942 int s_ip_idx, int *p_ip_idx, int netnsid)
4918{
4943{
4944 struct inet6_fill_args fillargs = {
4945 .portid = NETLINK_CB(cb->skb).portid,
4946 .seq = cb->nlh->nlmsg_seq,
4947 .flags = NLM_F_MULTI,
4948 .netnsid = netnsid,
4949 };
4919 struct ifmcaddr6 *ifmca;
4920 struct ifacaddr6 *ifaca;
4921 int err = 1;
4922 int ip_idx = *p_ip_idx;
4923
4924 read_lock_bh(&idev->lock);
4925 switch (type) {
4926 case UNICAST_ADDR: {
4927 struct inet6_ifaddr *ifa;
4950 struct ifmcaddr6 *ifmca;
4951 struct ifacaddr6 *ifaca;
4952 int err = 1;
4953 int ip_idx = *p_ip_idx;
4954
4955 read_lock_bh(&idev->lock);
4956 switch (type) {
4957 case UNICAST_ADDR: {
4958 struct inet6_ifaddr *ifa;
4959 fillargs.event = RTM_NEWADDR;
4928
4929 /* unicast address incl. temp addr */
4930 list_for_each_entry(ifa, &idev->addr_list, if_list) {
4931 if (++ip_idx < s_ip_idx)
4932 continue;
4960
4961 /* unicast address incl. temp addr */
4962 list_for_each_entry(ifa, &idev->addr_list, if_list) {
4963 if (++ip_idx < s_ip_idx)
4964 continue;
4933 err = inet6_fill_ifaddr(skb, ifa,
4934 NETLINK_CB(cb->skb).portid,
4935 cb->nlh->nlmsg_seq,
4936 RTM_NEWADDR,
4937 NLM_F_MULTI);
4965 err = inet6_fill_ifaddr(skb, ifa, &fillargs);
4938 if (err < 0)
4939 break;
4940 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
4941 }
4942 break;
4943 }
4944 case MULTICAST_ADDR:
4966 if (err < 0)
4967 break;
4968 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
4969 }
4970 break;
4971 }
4972 case MULTICAST_ADDR:
4973 fillargs.event = RTM_GETMULTICAST;
4974
4945 /* multicast address */
4946 for (ifmca = idev->mc_list; ifmca;
4947 ifmca = ifmca->next, ip_idx++) {
4948 if (ip_idx < s_ip_idx)
4949 continue;
4975 /* multicast address */
4976 for (ifmca = idev->mc_list; ifmca;
4977 ifmca = ifmca->next, ip_idx++) {
4978 if (ip_idx < s_ip_idx)
4979 continue;
4950 err = inet6_fill_ifmcaddr(skb, ifmca,
4951 NETLINK_CB(cb->skb).portid,
4952 cb->nlh->nlmsg_seq,
4953 RTM_GETMULTICAST,
4954 NLM_F_MULTI);
4980 err = inet6_fill_ifmcaddr(skb, ifmca, &fillargs);
4955 if (err < 0)
4956 break;
4957 }
4958 break;
4959 case ANYCAST_ADDR:
4981 if (err < 0)
4982 break;
4983 }
4984 break;
4985 case ANYCAST_ADDR:
4986 fillargs.event = RTM_GETANYCAST;
4960 /* anycast address */
4961 for (ifaca = idev->ac_list; ifaca;
4962 ifaca = ifaca->aca_next, ip_idx++) {
4963 if (ip_idx < s_ip_idx)
4964 continue;
4987 /* anycast address */
4988 for (ifaca = idev->ac_list; ifaca;
4989 ifaca = ifaca->aca_next, ip_idx++) {
4990 if (ip_idx < s_ip_idx)
4991 continue;
4965 err = inet6_fill_ifacaddr(skb, ifaca,
4966 NETLINK_CB(cb->skb).portid,
4967 cb->nlh->nlmsg_seq,
4968 RTM_GETANYCAST,
4969 NLM_F_MULTI);
4992 err = inet6_fill_ifacaddr(skb, ifaca, &fillargs);
4970 if (err < 0)
4971 break;
4972 }
4973 break;
4974 default:
4975 break;
4976 }
4977 read_unlock_bh(&idev->lock);
4978 *p_ip_idx = ip_idx;
4979 return err;
4980}
4981
4982static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
4983 enum addr_type_t type)
4984{
4985 struct net *net = sock_net(skb->sk);
4993 if (err < 0)
4994 break;
4995 }
4996 break;
4997 default:
4998 break;
4999 }
5000 read_unlock_bh(&idev->lock);
5001 *p_ip_idx = ip_idx;
5002 return err;
5003}
5004
5005static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
5006 enum addr_type_t type)
5007{
5008 struct net *net = sock_net(skb->sk);
5009 struct nlattr *tb[IFA_MAX+1];
5010 struct net *tgt_net = net;
5011 int netnsid = -1;
4986 int h, s_h;
4987 int idx, ip_idx;
4988 int s_idx, s_ip_idx;
4989 struct net_device *dev;
4990 struct inet6_dev *idev;
4991 struct hlist_head *head;
4992
4993 s_h = cb->args[0];
4994 s_idx = idx = cb->args[1];
4995 s_ip_idx = ip_idx = cb->args[2];
4996
5012 int h, s_h;
5013 int idx, ip_idx;
5014 int s_idx, s_ip_idx;
5015 struct net_device *dev;
5016 struct inet6_dev *idev;
5017 struct hlist_head *head;
5018
5019 s_h = cb->args[0];
5020 s_idx = idx = cb->args[1];
5021 s_ip_idx = ip_idx = cb->args[2];
5022
5023 if (nlmsg_parse(cb->nlh, sizeof(struct ifaddrmsg), tb, IFA_MAX,
5024 ifa_ipv6_policy, cb->extack) >= 0) {
5025 if (tb[IFA_TARGET_NETNSID]) {
5026 netnsid = nla_get_s32(tb[IFA_TARGET_NETNSID]);
5027
5028 tgt_net = rtnl_get_net_ns_capable(skb->sk, netnsid);
5029 if (IS_ERR(tgt_net))
5030 return PTR_ERR(tgt_net);
5031 }
5032 }
5033
4997 rcu_read_lock();
5034 rcu_read_lock();
4998 cb->seq = atomic_read(&net->ipv6.dev_addr_genid) ^ net->dev_base_seq;
5035 cb->seq = atomic_read(&tgt_net->ipv6.dev_addr_genid) ^ tgt_net->dev_base_seq;
4999 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
5000 idx = 0;
5036 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
5037 idx = 0;
5001 head = &net->dev_index_head[h];
5038 head = &tgt_net->dev_index_head[h];
5002 hlist_for_each_entry_rcu(dev, head, index_hlist) {
5003 if (idx < s_idx)
5004 goto cont;
5005 if (h > s_h || idx > s_idx)
5006 s_ip_idx = 0;
5007 ip_idx = 0;
5008 idev = __in6_dev_get(dev);
5009 if (!idev)
5010 goto cont;
5011
5012 if (in6_dump_addrs(idev, skb, cb, type,
5039 hlist_for_each_entry_rcu(dev, head, index_hlist) {
5040 if (idx < s_idx)
5041 goto cont;
5042 if (h > s_h || idx > s_idx)
5043 s_ip_idx = 0;
5044 ip_idx = 0;
5045 idev = __in6_dev_get(dev);
5046 if (!idev)
5047 goto cont;
5048
5049 if (in6_dump_addrs(idev, skb, cb, type,
5013 s_ip_idx, &ip_idx) < 0)
5050 s_ip_idx, &ip_idx, netnsid) < 0)
5014 goto done;
5015cont:
5016 idx++;
5017 }
5018 }
5019done:
5020 rcu_read_unlock();
5021 cb->args[0] = h;
5022 cb->args[1] = idx;
5023 cb->args[2] = ip_idx;
5051 goto done;
5052cont:
5053 idx++;
5054 }
5055 }
5056done:
5057 rcu_read_unlock();
5058 cb->args[0] = h;
5059 cb->args[1] = idx;
5060 cb->args[2] = ip_idx;
5061 if (netnsid >= 0)
5062 put_net(tgt_net);
5024
5025 return skb->len;
5026}
5027
5028static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
5029{
5030 enum addr_type_t type = UNICAST_ADDR;
5031

--- 14 unchanged lines hidden (view full) ---

5046
5047 return inet6_dump_addr(skb, cb, type);
5048}
5049
5050static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
5051 struct netlink_ext_ack *extack)
5052{
5053 struct net *net = sock_net(in_skb->sk);
5063
5064 return skb->len;
5065}
5066
5067static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
5068{
5069 enum addr_type_t type = UNICAST_ADDR;
5070

--- 14 unchanged lines hidden (view full) ---

5085
5086 return inet6_dump_addr(skb, cb, type);
5087}
5088
5089static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
5090 struct netlink_ext_ack *extack)
5091{
5092 struct net *net = sock_net(in_skb->sk);
5093 struct inet6_fill_args fillargs = {
5094 .portid = NETLINK_CB(in_skb).portid,
5095 .seq = nlh->nlmsg_seq,
5096 .event = RTM_NEWADDR,
5097 .flags = 0,
5098 .netnsid = -1,
5099 };
5100 struct net *tgt_net = net;
5054 struct ifaddrmsg *ifm;
5055 struct nlattr *tb[IFA_MAX+1];
5056 struct in6_addr *addr = NULL, *peer;
5057 struct net_device *dev = NULL;
5058 struct inet6_ifaddr *ifa;
5059 struct sk_buff *skb;
5060 int err;
5061
5062 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy,
5063 extack);
5064 if (err < 0)
5065 return err;
5066
5101 struct ifaddrmsg *ifm;
5102 struct nlattr *tb[IFA_MAX+1];
5103 struct in6_addr *addr = NULL, *peer;
5104 struct net_device *dev = NULL;
5105 struct inet6_ifaddr *ifa;
5106 struct sk_buff *skb;
5107 int err;
5108
5109 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy,
5110 extack);
5111 if (err < 0)
5112 return err;
5113
5114 if (tb[IFA_TARGET_NETNSID]) {
5115 fillargs.netnsid = nla_get_s32(tb[IFA_TARGET_NETNSID]);
5116
5117 tgt_net = rtnl_get_net_ns_capable(NETLINK_CB(in_skb).sk,
5118 fillargs.netnsid);
5119 if (IS_ERR(tgt_net))
5120 return PTR_ERR(tgt_net);
5121 }
5122
5067 addr = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL], &peer);
5068 if (!addr)
5069 return -EINVAL;
5070
5071 ifm = nlmsg_data(nlh);
5072 if (ifm->ifa_index)
5123 addr = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL], &peer);
5124 if (!addr)
5125 return -EINVAL;
5126
5127 ifm = nlmsg_data(nlh);
5128 if (ifm->ifa_index)
5073 dev = dev_get_by_index(net, ifm->ifa_index);
5129 dev = dev_get_by_index(tgt_net, ifm->ifa_index);
5074
5130
5075 ifa = ipv6_get_ifaddr(net, addr, dev, 1);
5131 ifa = ipv6_get_ifaddr(tgt_net, addr, dev, 1);
5076 if (!ifa) {
5077 err = -EADDRNOTAVAIL;
5078 goto errout;
5079 }
5080
5081 skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_KERNEL);
5082 if (!skb) {
5083 err = -ENOBUFS;
5084 goto errout_ifa;
5085 }
5086
5132 if (!ifa) {
5133 err = -EADDRNOTAVAIL;
5134 goto errout;
5135 }
5136
5137 skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_KERNEL);
5138 if (!skb) {
5139 err = -ENOBUFS;
5140 goto errout_ifa;
5141 }
5142
5087 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).portid,
5088 nlh->nlmsg_seq, RTM_NEWADDR, 0);
5143 err = inet6_fill_ifaddr(skb, ifa, &fillargs);
5089 if (err < 0) {
5090 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
5091 WARN_ON(err == -EMSGSIZE);
5092 kfree_skb(skb);
5093 goto errout_ifa;
5094 }
5144 if (err < 0) {
5145 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
5146 WARN_ON(err == -EMSGSIZE);
5147 kfree_skb(skb);
5148 goto errout_ifa;
5149 }
5095 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
5150 err = rtnl_unicast(skb, tgt_net, NETLINK_CB(in_skb).portid);
5096errout_ifa:
5097 in6_ifa_put(ifa);
5098errout:
5099 if (dev)
5100 dev_put(dev);
5151errout_ifa:
5152 in6_ifa_put(ifa);
5153errout:
5154 if (dev)
5155 dev_put(dev);
5156 if (fillargs.netnsid >= 0)
5157 put_net(tgt_net);
5158
5101 return err;
5102}
5103
5104static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
5105{
5106 struct sk_buff *skb;
5107 struct net *net = dev_net(ifa->idev->dev);
5159 return err;
5160}
5161
5162static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
5163{
5164 struct sk_buff *skb;
5165 struct net *net = dev_net(ifa->idev->dev);
5166 struct inet6_fill_args fillargs = {
5167 .portid = 0,
5168 .seq = 0,
5169 .event = event,
5170 .flags = 0,
5171 .netnsid = -1,
5172 };
5108 int err = -ENOBUFS;
5109
5110 skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC);
5111 if (!skb)
5112 goto errout;
5113
5173 int err = -ENOBUFS;
5174
5175 skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC);
5176 if (!skb)
5177 goto errout;
5178
5114 err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0);
5179 err = inet6_fill_ifaddr(skb, ifa, &fillargs);
5115 if (err < 0) {
5116 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
5117 WARN_ON(err == -EMSGSIZE);
5118 kfree_skb(skb);
5119 goto errout;
5120 }
5121 rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
5122 return;

--- 1714 unchanged lines hidden ---
5180 if (err < 0) {
5181 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
5182 WARN_ON(err == -EMSGSIZE);
5183 kfree_skb(skb);
5184 goto errout;
5185 }
5186 rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
5187 return;

--- 1714 unchanged lines hidden ---