Hi Jeff, 

Jeff Dike wrote:


Your subject should indicate net or net-next as the tree, please see:
https://www.kernel.org/doc/html/latest/networking/netdev-FAQ.html

> Commit 58956317c8de guarantees arp table entries a five-second lifetime.  We 
> have some apps which make heavy use of multicast, and these can cause the 
> table to overflow by filling it with multicast addresses which can't be GC-ed 
> until their five seconds are up.
> This patch allows multicast addresses to be thrown out before they've lived 
> out their five seconds.

Not sure how many patches you've submitted, but your commit message
should be wrapped at 68 or 72 characters or so.

> 
> Signed-off-by: Jeff Dike <jd...@akamai.com>

your triple-dash and a diffstat should be right here, did you hand edit
this mail instead of using git format-patch to generate it?

> 
> diff --git a/include/net/neighbour.h b/include/net/neighbour.h
> index 81ee17594c32..22ced1381ede 100644
> --- a/include/net/neighbour.h
> +++ b/include/net/neighbour.h
> @@ -204,6 +204,7 @@ struct neigh_table {
>       int                     (*pconstructor)(struct pneigh_entry *);
>       void                    (*pdestructor)(struct pneigh_entry *);
>       void                    (*proxy_redo)(struct sk_buff *skb);
> +     int                     (*is_multicast)(const void *pkey);
>       bool                    (*allow_add)(const struct net_device *dev,
>                                            struct netlink_ext_ack *extack);
>       char                    *id;
> diff --git a/net/core/neighbour.c b/net/core/neighbour.c
> index 8e39e28b0a8d..9500d28a43b0 100644
> --- a/net/core/neighbour.c
> +++ b/net/core/neighbour.c
> @@ -235,6 +235,8 @@ static int neigh_forced_gc(struct neigh_table *tbl)
>  
>                       write_lock(&n->lock);
>                       if ((n->nud_state == NUD_FAILED) ||
> +                         (tbl->is_multicast &&
> +                          tbl->is_multicast(n->primary_key)) ||
>                           time_after(tref, n->updated))
>                               remove = true;
>                       write_unlock(&n->lock);
> diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
> index 687971d83b4e..110d6d408edc 100644
> --- a/net/ipv4/arp.c
> +++ b/net/ipv4/arp.c
> @@ -79,6 +79,7 @@
>  #include <linux/socket.h>
>  #include <linux/sockios.h>
>  #include <linux/errno.h>
> +#define __UAPI_DEF_IN_CLASS 1

Why is this added in the middle of the includes?

>  #include <linux/in.h>
>  #include <linux/mm.h>
>  #include <linux/inet.h>
> @@ -125,6 +126,7 @@ static int arp_constructor(struct neighbour *neigh);
>  static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb);
>  static void arp_error_report(struct neighbour *neigh, struct sk_buff *skb);
>  static void parp_redo(struct sk_buff *skb);
> +static int arp_is_multicast(const void *pkey);
>  
>  static const struct neigh_ops arp_generic_ops = {
>       .family =               AF_INET,
> @@ -156,6 +158,7 @@ struct neigh_table arp_tbl = {
>       .key_eq         = arp_key_eq,
>       .constructor    = arp_constructor,
>       .proxy_redo     = parp_redo,
> +     .is_multicast   = arp_is_multicast,
>       .id             = "arp_cache",
>       .parms          = {
>               .tbl                    = &arp_tbl,
> @@ -928,6 +931,10 @@ static void parp_redo(struct sk_buff *skb)
>       arp_process(dev_net(skb->dev), NULL, skb);
>  }
>  
> +static int arp_is_multicast(const void *pkey)
> +{
> +     return IN_MULTICAST(htonl(*((u32 *) pkey)));
> +}

Why not just move this function up and skip the declaration above?

>  
>  /*
>   *   Receive an arp request from the device layer.
> diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
> index 27f29b957ee7..b42c9314cc4e 100644
> --- a/net/ipv6/ndisc.c
> +++ b/net/ipv6/ndisc.c
> @@ -81,6 +81,7 @@ static void ndisc_error_report(struct neighbour *neigh, 
> struct sk_buff *skb);
>  static int pndisc_constructor(struct pneigh_entry *n);
>  static void pndisc_destructor(struct pneigh_entry *n);
>  static void pndisc_redo(struct sk_buff *skb);
> +static int ndisc_is_multicast(const void *pkey);
>  
>  static const struct neigh_ops ndisc_generic_ops = {
>       .family =               AF_INET6,
> @@ -115,6 +116,7 @@ struct neigh_table nd_tbl = {
>       .pconstructor = pndisc_constructor,
>       .pdestructor =  pndisc_destructor,
>       .proxy_redo =   pndisc_redo,
> +     .is_multicast = ndisc_is_multicast,
>       .allow_add  =   ndisc_allow_add,
>       .id =           "ndisc_cache",
>       .parms = {
> @@ -1706,6 +1708,11 @@ static void pndisc_redo(struct sk_buff *skb)
>       kfree_skb(skb);
>  }
>  
> +static int ndisc_is_multicast(const void *pkey)
> +{
> +     return (((struct in6_addr *) pkey)->in6_u.u6_addr8[0] & 0xf0) == 0xf0;
> +}
> +

Again, just move this up above the first usage?

Does the above work on big and little endian, just seems suspicious
even though you're using a byte offset? Also I suspect this will
trigger a warning with sparse or with W=2 about pointer alignment.

Reply via email to