Skip to content

Commit 6371a71

Browse files
dsaherndavem330
authored andcommitted
net/ipv6: Add support for dumping addresses for a specific device
If an RTM_GETADDR dump request has ifa_index set in the ifaddrmsg header, then return only the addresses for that device. Since inet6_dump_addr is reused for multicast and anycast addresses, this adds support for device specfic dumps of RTM_GETMULTICAST and RTM_GETANYCAST as well. Signed-off-by: David Ahern <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 5fcd266 commit 6371a71

File tree

1 file changed

+22
-5
lines changed

1 file changed

+22
-5
lines changed

net/ipv6/addrconf.c

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4821,6 +4821,7 @@ struct inet6_fill_args {
48214821
int event;
48224822
unsigned int flags;
48234823
int netnsid;
4824+
int ifindex;
48244825
enum addr_type_t type;
48254826
};
48264827

@@ -5018,8 +5019,9 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
50185019
static int inet6_valid_dump_ifaddr_req(const struct nlmsghdr *nlh,
50195020
struct inet6_fill_args *fillargs,
50205021
struct net **tgt_net, struct sock *sk,
5021-
struct netlink_ext_ack *extack)
5022+
struct netlink_callback *cb)
50225023
{
5024+
struct netlink_ext_ack *extack = cb->extack;
50235025
struct nlattr *tb[IFA_MAX+1];
50245026
struct ifaddrmsg *ifm;
50255027
int err, i;
@@ -5034,9 +5036,11 @@ static int inet6_valid_dump_ifaddr_req(const struct nlmsghdr *nlh,
50345036
NL_SET_ERR_MSG_MOD(extack, "Invalid values in header for address dump request");
50355037
return -EINVAL;
50365038
}
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;
50405044
}
50415045

50425046
err = nlmsg_parse_strict(nlh, sizeof(*ifm), tb, IFA_MAX,
@@ -5094,9 +5098,21 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
50945098
int err;
50955099

50965100
err = inet6_valid_dump_ifaddr_req(nlh, &fillargs, &tgt_net,
5097-
skb->sk, cb->extack);
5101+
skb->sk, cb);
50985102
if (err < 0)
50995103
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+
}
51005116
}
51015117

51025118
rcu_read_lock();
@@ -5124,6 +5140,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
51245140
rcu_read_unlock();
51255141
cb->args[0] = h;
51265142
cb->args[1] = idx;
5143+
put_tgt_net:
51275144
if (fillargs.netnsid >= 0)
51285145
put_net(tgt_net);
51295146

0 commit comments

Comments
 (0)