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