addrconf.c (fe884c2be0b329042eaf0371ebdbb636ba3ccc39) | addrconf.c (6371a71f3a3b2bc47880dd76c2f176495802d0df) |
---|---|
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 * --- 4807 unchanged lines hidden (view full) --- 4816}; 4817 4818struct inet6_fill_args { 4819 u32 portid; 4820 u32 seq; 4821 int event; 4822 unsigned int flags; 4823 int netnsid; | 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 * --- 4807 unchanged lines hidden (view full) --- 4816}; 4817 4818struct inet6_fill_args { 4819 u32 portid; 4820 u32 seq; 4821 int event; 4822 unsigned int flags; 4823 int netnsid; |
4824 int ifindex; |
|
4824 enum addr_type_t type; 4825}; 4826 4827static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, 4828 struct inet6_fill_args *args) 4829{ 4830 struct nlmsghdr *nlh; 4831 u32 preferred, valid; --- 181 unchanged lines hidden (view full) --- 5013 read_unlock_bh(&idev->lock); 5014 cb->args[2] = ip_idx; 5015 return err; 5016} 5017 5018static int inet6_valid_dump_ifaddr_req(const struct nlmsghdr *nlh, 5019 struct inet6_fill_args *fillargs, 5020 struct net **tgt_net, struct sock *sk, | 4825 enum addr_type_t type; 4826}; 4827 4828static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, 4829 struct inet6_fill_args *args) 4830{ 4831 struct nlmsghdr *nlh; 4832 u32 preferred, valid; --- 181 unchanged lines hidden (view full) --- 5014 read_unlock_bh(&idev->lock); 5015 cb->args[2] = ip_idx; 5016 return err; 5017} 5018 5019static int inet6_valid_dump_ifaddr_req(const struct nlmsghdr *nlh, 5020 struct inet6_fill_args *fillargs, 5021 struct net **tgt_net, struct sock *sk, |
5021 struct netlink_ext_ack *extack) | 5022 struct netlink_callback *cb) |
5022{ | 5023{ |
5024 struct netlink_ext_ack *extack = cb->extack; |
|
5023 struct nlattr *tb[IFA_MAX+1]; 5024 struct ifaddrmsg *ifm; 5025 int err, i; 5026 5027 if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifm))) { 5028 NL_SET_ERR_MSG_MOD(extack, "Invalid header for address dump request"); 5029 return -EINVAL; 5030 } 5031 5032 ifm = nlmsg_data(nlh); 5033 if (ifm->ifa_prefixlen || ifm->ifa_flags || ifm->ifa_scope) { 5034 NL_SET_ERR_MSG_MOD(extack, "Invalid values in header for address dump request"); 5035 return -EINVAL; 5036 } | 5025 struct nlattr *tb[IFA_MAX+1]; 5026 struct ifaddrmsg *ifm; 5027 int err, i; 5028 5029 if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifm))) { 5030 NL_SET_ERR_MSG_MOD(extack, "Invalid header for address dump request"); 5031 return -EINVAL; 5032 } 5033 5034 ifm = nlmsg_data(nlh); 5035 if (ifm->ifa_prefixlen || ifm->ifa_flags || ifm->ifa_scope) { 5036 NL_SET_ERR_MSG_MOD(extack, "Invalid values in header for address dump request"); 5037 return -EINVAL; 5038 } |
5037 if (ifm->ifa_index) { 5038 NL_SET_ERR_MSG_MOD(extack, "Filter by device index not supported for address dump"); 5039 return -EINVAL; | 5039 5040 fillargs->ifindex = ifm->ifa_index; 5041 if (fillargs->ifindex) { 5042 cb->answer_flags |= NLM_F_DUMP_FILTERED; 5043 fillargs->flags |= NLM_F_DUMP_FILTERED; |
5040 } 5041 5042 err = nlmsg_parse_strict(nlh, sizeof(*ifm), tb, IFA_MAX, 5043 ifa_ipv6_policy, extack); 5044 if (err < 0) 5045 return err; 5046 5047 for (i = 0; i <= IFA_MAX; ++i) { --- 41 unchanged lines hidden (view full) --- 5089 s_h = cb->args[0]; 5090 s_idx = idx = cb->args[1]; 5091 s_ip_idx = cb->args[2]; 5092 5093 if (cb->strict_check) { 5094 int err; 5095 5096 err = inet6_valid_dump_ifaddr_req(nlh, &fillargs, &tgt_net, | 5044 } 5045 5046 err = nlmsg_parse_strict(nlh, sizeof(*ifm), tb, IFA_MAX, 5047 ifa_ipv6_policy, extack); 5048 if (err < 0) 5049 return err; 5050 5051 for (i = 0; i <= IFA_MAX; ++i) { --- 41 unchanged lines hidden (view full) --- 5093 s_h = cb->args[0]; 5094 s_idx = idx = cb->args[1]; 5095 s_ip_idx = cb->args[2]; 5096 5097 if (cb->strict_check) { 5098 int err; 5099 5100 err = inet6_valid_dump_ifaddr_req(nlh, &fillargs, &tgt_net, |
5097 skb->sk, cb->extack); | 5101 skb->sk, cb); |
5098 if (err < 0) 5099 return err; | 5102 if (err < 0) 5103 return err; |
5104 5105 if (fillargs.ifindex) { 5106 dev = __dev_get_by_index(tgt_net, fillargs.ifindex); 5107 if (!dev) 5108 return -ENODEV; 5109 idev = __in6_dev_get(dev); 5110 if (idev) { 5111 err = in6_dump_addrs(idev, skb, cb, s_ip_idx, 5112 &fillargs); 5113 } 5114 goto put_tgt_net; 5115 } |
|
5100 } 5101 5102 rcu_read_lock(); 5103 cb->seq = atomic_read(&tgt_net->ipv6.dev_addr_genid) ^ tgt_net->dev_base_seq; 5104 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { 5105 idx = 0; 5106 head = &tgt_net->dev_index_head[h]; 5107 hlist_for_each_entry_rcu(dev, head, index_hlist) { --- 11 unchanged lines hidden (view full) --- 5119cont: 5120 idx++; 5121 } 5122 } 5123done: 5124 rcu_read_unlock(); 5125 cb->args[0] = h; 5126 cb->args[1] = idx; | 5116 } 5117 5118 rcu_read_lock(); 5119 cb->seq = atomic_read(&tgt_net->ipv6.dev_addr_genid) ^ tgt_net->dev_base_seq; 5120 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { 5121 idx = 0; 5122 head = &tgt_net->dev_index_head[h]; 5123 hlist_for_each_entry_rcu(dev, head, index_hlist) { --- 11 unchanged lines hidden (view full) --- 5135cont: 5136 idx++; 5137 } 5138 } 5139done: 5140 rcu_read_unlock(); 5141 cb->args[0] = h; 5142 cb->args[1] = idx; |
5143put_tgt_net: |
|
5127 if (fillargs.netnsid >= 0) 5128 put_net(tgt_net); 5129 5130 return skb->len; 5131} 5132 5133static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) 5134{ --- 1868 unchanged lines hidden --- | 5144 if (fillargs.netnsid >= 0) 5145 put_net(tgt_net); 5146 5147 return skb->len; 5148} 5149 5150static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) 5151{ --- 1868 unchanged lines hidden --- |