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