David Ahern <d...@cumulusnetworks.com> writes:

> Add support for filtering neighbor dumps by master device by adding
> the NDA_MASTER attribute to the dump request. A new netlink flag,
> NLM_F_DUMP_FILTERED, is added to indicate the kernel supports the
> request and output is filtered as requested.

*Scratches my head*

I thought you only wanted L3 functionality, and that you did not want a
network namespace.

What is the thinking here because it sure looks like you are busily
adding layer two functionality you swore you did not want.

Eric

> Signed-off-by: David Ahern <d...@cumulusnetworks.com>
> ---
> v2
> - added NLM_F_DUMP_FILTERED flag for userspace feedback that request is
>   supported
>
> This method works for other filters as well and other dump commands.
> Works fine for all combinations of new and old kernel and new and old ip:
> 1. new ip command on old kernel, NDA_MASTER attribute is ignored
> 2. old ip command on new kernel, NDA_MASTER attribute is not present
> 3. new ip on new kernel ... goodness ensues by limiting data to
>    only what user wants
>
>  include/uapi/linux/netlink.h |  1 +
>  net/core/neighbour.c         | 32 +++++++++++++++++++++++++++++++-
>  2 files changed, 32 insertions(+), 1 deletion(-)
>
> diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h
> index 6f3fe16cd22a..f095155d8749 100644
> --- a/include/uapi/linux/netlink.h
> +++ b/include/uapi/linux/netlink.h
> @@ -54,6 +54,7 @@ struct nlmsghdr {
>  #define NLM_F_ACK            4       /* Reply with ack, with zero or error 
> code */
>  #define NLM_F_ECHO           8       /* Echo this request            */
>  #define NLM_F_DUMP_INTR              16      /* Dump was inconsistent due to 
> sequence change */
> +#define NLM_F_DUMP_FILTERED  32      /* Dump was filtered as requested */
>  
>  /* Modifiers to GET request */
>  #define NLM_F_ROOT   0x100   /* specify tree root    */
> diff --git a/net/core/neighbour.c b/net/core/neighbour.c
> index 2b515ba7e94f..8c57fdf4d68e 100644
> --- a/net/core/neighbour.c
> +++ b/net/core/neighbour.c
> @@ -2235,14 +2235,42 @@ static void neigh_update_notify(struct neighbour 
> *neigh)
>       __neigh_notify(neigh, RTM_NEWNEIGH, 0);
>  }
>  
> +static bool neigh_master_filtered(struct net_device *dev, int master_idx)
> +{
> +     struct net_device *master;
> +
> +     if (!master_idx)
> +             return false;
> +
> +     master = netdev_master_upper_dev_get(dev);
> +     if (!master || master->ifindex != master_idx)
> +             return true;
> +
> +     return false;
> +}
> +
>  static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
>                           struct netlink_callback *cb)
>  {
>       struct net *net = sock_net(skb->sk);
> +     const struct nlmsghdr *nlh = cb->nlh;
> +     struct nlattr *tb[NDA_MAX + 1];
>       struct neighbour *n;
>       int rc, h, s_h = cb->args[1];
>       int idx, s_idx = idx = cb->args[2];
>       struct neigh_hash_table *nht;
> +     int filter_master_idx = 0;
> +     unsigned int flags = NLM_F_MULTI;
> +     int err;
> +
> +     err = nlmsg_parse(nlh, sizeof(struct ndmsg), tb, NDA_MAX, NULL);
> +     if (!err) {
> +             if (tb[NDA_MASTER])
> +                     filter_master_idx = nla_get_u32(tb[NDA_MASTER]);
> +
> +             if (filter_master_idx)
> +                     flags |= NLM_F_DUMP_FILTERED;
> +     }
>  
>       rcu_read_lock_bh();
>       nht = rcu_dereference_bh(tbl->nht);
> @@ -2255,12 +2283,14 @@ static int neigh_dump_table(struct neigh_table *tbl, 
> struct sk_buff *skb,
>                    n = rcu_dereference_bh(n->next)) {
>                       if (!net_eq(dev_net(n->dev), net))
>                               continue;
> +                     if (neigh_master_filtered(n->dev, filter_master_idx))
> +                             continue;
>                       if (idx < s_idx)
>                               goto next;
>                       if (neigh_fill_info(skb, n, NETLINK_CB(cb->skb).portid,
>                                           cb->nlh->nlmsg_seq,
>                                           RTM_NEWNEIGH,
> -                                         NLM_F_MULTI) < 0) {
> +                                         flags) < 0) {
>                               rc = -1;
>                               goto out;
>                       }
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to