On Fri, Sep 28, 2018 at 08:44:59AM -0700, dsah...@kernel.org wrote: > From: David Ahern <dsah...@gmail.com> > > Pull the inet6_fill_args arg up to in6_dump_addrs and move netnsid > into it. Since IFA_TARGET_NETNSID is a kernel side filter add the > NLM_F_DUMP_FILTERED flag so userspace knows the request was honored. > > Signed-off-by: David Ahern <dsah...@gmail.com>
Acked-by: Christian Brauner <christ...@brauner.io> > --- > net/ipv6/addrconf.c | 59 > +++++++++++++++++++++++++++++------------------------ > 1 file changed, 32 insertions(+), 27 deletions(-) > > diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c > index a9a317322388..375ea9d9869b 100644 > --- a/net/ipv6/addrconf.c > +++ b/net/ipv6/addrconf.c > @@ -4793,12 +4793,19 @@ static inline int inet6_ifaddr_msgsize(void) > + nla_total_size(4) /* IFA_RT_PRIORITY */; > } > > +enum addr_type_t { > + UNICAST_ADDR, > + MULTICAST_ADDR, > + ANYCAST_ADDR, > +}; > + > struct inet6_fill_args { > u32 portid; > u32 seq; > int event; > unsigned int flags; > int netnsid; > + enum addr_type_t type; > }; > > static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, > @@ -4930,39 +4937,28 @@ static int inet6_fill_ifacaddr(struct sk_buff *skb, > struct ifacaddr6 *ifaca, > return 0; > } > > -enum addr_type_t { > - UNICAST_ADDR, > - MULTICAST_ADDR, > - ANYCAST_ADDR, > -}; > - > /* called with rcu_read_lock() */ > static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb, > - struct netlink_callback *cb, enum addr_type_t type, > - int s_ip_idx, int *p_ip_idx, int netnsid) > + struct netlink_callback *cb, > + int s_ip_idx, int *p_ip_idx, > + struct inet6_fill_args *fillargs) > { > - struct inet6_fill_args fillargs = { > - .portid = NETLINK_CB(cb->skb).portid, > - .seq = cb->nlh->nlmsg_seq, > - .flags = NLM_F_MULTI, > - .netnsid = netnsid, > - }; > struct ifmcaddr6 *ifmca; > struct ifacaddr6 *ifaca; > int err = 1; > int ip_idx = *p_ip_idx; > > read_lock_bh(&idev->lock); > - switch (type) { > + switch (fillargs->type) { > case UNICAST_ADDR: { > struct inet6_ifaddr *ifa; > - fillargs.event = RTM_NEWADDR; > + fillargs->event = RTM_NEWADDR; > > /* unicast address incl. temp addr */ > list_for_each_entry(ifa, &idev->addr_list, if_list) { > if (++ip_idx < s_ip_idx) > continue; > - err = inet6_fill_ifaddr(skb, ifa, &fillargs); > + err = inet6_fill_ifaddr(skb, ifa, fillargs); > if (err < 0) > break; > nl_dump_check_consistent(cb, nlmsg_hdr(skb)); > @@ -4970,26 +4966,26 @@ static int in6_dump_addrs(struct inet6_dev *idev, > struct sk_buff *skb, > break; > } > case MULTICAST_ADDR: > - fillargs.event = RTM_GETMULTICAST; > + fillargs->event = RTM_GETMULTICAST; > > /* multicast address */ > for (ifmca = idev->mc_list; ifmca; > ifmca = ifmca->next, ip_idx++) { > if (ip_idx < s_ip_idx) > continue; > - err = inet6_fill_ifmcaddr(skb, ifmca, &fillargs); > + err = inet6_fill_ifmcaddr(skb, ifmca, fillargs); > if (err < 0) > break; > } > break; > case ANYCAST_ADDR: > - fillargs.event = RTM_GETANYCAST; > + fillargs->event = RTM_GETANYCAST; > /* anycast address */ > for (ifaca = idev->ac_list; ifaca; > ifaca = ifaca->aca_next, ip_idx++) { > if (ip_idx < s_ip_idx) > continue; > - err = inet6_fill_ifacaddr(skb, ifaca, &fillargs); > + err = inet6_fill_ifacaddr(skb, ifaca, fillargs); > if (err < 0) > break; > } > @@ -5005,10 +5001,16 @@ static int in6_dump_addrs(struct inet6_dev *idev, > struct sk_buff *skb, > static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, > enum addr_type_t type) > { > + struct inet6_fill_args fillargs = { > + .portid = NETLINK_CB(cb->skb).portid, > + .seq = cb->nlh->nlmsg_seq, > + .flags = NLM_F_MULTI, > + .netnsid = -1, > + .type = type, > + }; > struct net *net = sock_net(skb->sk); > struct nlattr *tb[IFA_MAX+1]; > struct net *tgt_net = net; > - int netnsid = -1; > int h, s_h; > int idx, ip_idx; > int s_idx, s_ip_idx; > @@ -5023,11 +5025,14 @@ static int inet6_dump_addr(struct sk_buff *skb, > struct netlink_callback *cb, > if (nlmsg_parse(cb->nlh, sizeof(struct ifaddrmsg), tb, IFA_MAX, > ifa_ipv6_policy, NULL) >= 0) { > if (tb[IFA_TARGET_NETNSID]) { > - netnsid = nla_get_s32(tb[IFA_TARGET_NETNSID]); > + fillargs.netnsid = nla_get_s32(tb[IFA_TARGET_NETNSID]); > > - tgt_net = rtnl_get_net_ns_capable(skb->sk, netnsid); > + tgt_net = rtnl_get_net_ns_capable(skb->sk, > + fillargs.netnsid); > if (IS_ERR(tgt_net)) > return PTR_ERR(tgt_net); > + > + fillargs.flags |= NLM_F_DUMP_FILTERED; > } > } > > @@ -5046,8 +5051,8 @@ static int inet6_dump_addr(struct sk_buff *skb, struct > netlink_callback *cb, > if (!idev) > goto cont; > > - if (in6_dump_addrs(idev, skb, cb, type, > - s_ip_idx, &ip_idx, netnsid) < 0) > + if (in6_dump_addrs(idev, skb, cb, s_ip_idx, &ip_idx, > + &fillargs) < 0) > goto done; > cont: > idx++; > @@ -5058,7 +5063,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct > netlink_callback *cb, > cb->args[0] = h; > cb->args[1] = idx; > cb->args[2] = ip_idx; > - if (netnsid >= 0) > + if (fillargs.netnsid >= 0) > put_net(tgt_net); > > return skb->len; > -- > 2.11.0 >