[PATCH 2/2] ip6mr: Make cache queue length configurable
From: Brodie Greenfield <hidden>
Date: 2019-03-07 04:57:43
Also in:
lkml
Subsystem:
documentation, networking [general], networking [ipv4/ipv6], the rest · Maintainers:
Jonathan Corbet, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, David Ahern, Ido Schimmel, Linus Torvalds
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 <redacted> --- 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) +ip6_mr_cache_queue_length - INTEGER + 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 + }, { } };
--
2.21.0