On 7/03/19 9:20 AM, Brodie Greenfield wrote: > We want to be able to keep more spaces available in our queue for > processing incoming IPv6 multicast traffic (adding (S,G) entries) - this > lets us learn more groups faster, rather than dropping them at this stage. > > Signed-off-by: Brodie Greenfield <brodie.greenfi...@alliedtelesis.co.nz> > --- > Documentation/networking/ip-sysctl.txt | 8 ++++++++ > include/net/netns/ipv6.h | 1 + > net/ipv6/af_inet6.c | 1 + > net/ipv6/ip6mr.c | 4 +++- > net/ipv6/sysctl_net_ipv6.c | 7 +++++++ > 5 files changed, 20 insertions(+), 1 deletion(-) > > diff --git a/Documentation/networking/ip-sysctl.txt > b/Documentation/networking/ip-sysctl.txt > index 02f77e932adf..68eada3ca915 100644 > --- a/Documentation/networking/ip-sysctl.txt > +++ b/Documentation/networking/ip-sysctl.txt > @@ -1481,6 +1481,14 @@ skip_notify_on_dev_down - BOOLEAN > on userspace caches to track link events and evict routes. > Default: false (generate message) > > +ip_mr_cache_queue_length - INTEGER
Should be "ip6_mr_cache_queue_length" for this patch. > + Limit the number of multicast packets we can have in the queue to be > + resolved. > + Bear in mind that when an unresolved multicast packet is received, > + there is an O(n) traversal of the queue. This should be considered > + if increasing. > + Default: 10 > + > IPv6 Fragmentation: > > ip6frag_high_thresh - INTEGER > diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h > index ef1ed529f33c..84b58424c799 100644 > --- a/include/net/netns/ipv6.h > +++ b/include/net/netns/ipv6.h > @@ -46,6 +46,7 @@ struct netns_sysctl_ipv6 { > int max_hbh_opts_len; > int seg6_flowlabel; > bool skip_notify_on_dev_down; > + unsigned int ip6_mr_cache_queue_length; > }; > > struct netns_ipv6 { > diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c > index d99753b5e39b..6551bb63e5a2 100644 > --- a/net/ipv6/af_inet6.c > +++ b/net/ipv6/af_inet6.c > @@ -856,6 +856,7 @@ static int __net_init inet6_net_init(struct net *net) > net->ipv6.sysctl.max_hbh_opts_cnt = IP6_DEFAULT_MAX_HBH_OPTS_CNT; > net->ipv6.sysctl.max_dst_opts_len = IP6_DEFAULT_MAX_DST_OPTS_LEN; > net->ipv6.sysctl.max_hbh_opts_len = IP6_DEFAULT_MAX_HBH_OPTS_LEN; > + net->ipv6.sysctl.ip6_mr_cache_queue_length = 10; > atomic_set(&net->ipv6.fib6_sernum, 1); > > err = ipv6_init_mibs(net); > diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c > index cc01aa3f2b5e..bb445871437e 100644 > --- a/net/ipv6/ip6mr.c > +++ b/net/ipv6/ip6mr.c > @@ -1135,6 +1135,7 @@ static int ip6mr_cache_report(struct mr_table *mrt, > struct sk_buff *pkt, > static int ip6mr_cache_unresolved(struct mr_table *mrt, mifi_t mifi, > struct sk_buff *skb, struct net_device *dev) > { > + struct net *net = dev_net(dev); > struct mfc6_cache *c; > bool found = false; > int err; > @@ -1153,7 +1154,8 @@ static int ip6mr_cache_unresolved(struct mr_table *mrt, > mifi_t mifi, > * Create a new entry if allowable > */ > > - if (atomic_read(&mrt->cache_resolve_queue_len) >= 10 || > + if (atomic_read(&mrt->cache_resolve_queue_len) >= > + net->ipv6.sysctl.ip6_mr_cache_queue_length || > (c = ip6mr_cache_alloc_unres()) == NULL) { > spin_unlock_bh(&mfc_unres_lock); > > diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c > index e15cd37024fd..a27299d4cc34 100644 > --- a/net/ipv6/sysctl_net_ipv6.c > +++ b/net/ipv6/sysctl_net_ipv6.c > @@ -159,6 +159,13 @@ static struct ctl_table ipv6_table_template[] = { > .mode = 0644, > .proc_handler = proc_dointvec > }, > + { > + .procname = "ip6_mr_cache_queue_length", > + .data = > &init_net.ipv6.sysctl.ip6_mr_cache_queue_length, > + .maxlen = sizeof(int), > + .mode = 0644, > + .proc_handler = proc_dointvec > + }, > { } > }; > >