All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/7] netconf: Add support for RTM_DELNETCONF
@ 2017-03-28 21:28 David Ahern
  2017-03-28 21:28 ` [PATCH net-next 1/7] rtnetlink: Add RTM_DELNETCONF David Ahern
                   ` (7 more replies)
  0 siblings, 8 replies; 12+ messages in thread
From: David Ahern @ 2017-03-28 21:28 UTC (permalink / raw)
  To: netdev; +Cc: nicolas.dichtel, David Ahern

netconf notifications are sent as devices register but not when they
are deleted leaving userspace caches out of sync. Add support for
RTM_DELNETCONF to ipv4, ipv6 and mpls.

MPLS is missing RTM_NEWNETCONF as devices are created, so add it as well.

David Ahern (7):
  rtnetlink: Add RTM_DELNETCONF
  net: devinet: Refactor inet_netconf_notify_devconf to take event
  net: devinet: Add support for RTM_DELNETCONF
  net: ipv6: Refactor inet6_netconf_notify_devconf to take event
  net: ipv6: Add support for RTM_DELNETCONF
  net:mpls: Refactor mpls_netconf_notify_devconf to take event
  net: mpls: Send netconf messages on device register and unregister

 include/linux/inetdevice.h     |  4 +--
 include/net/addrconf.h         |  4 +--
 include/uapi/linux/rtnetlink.h |  2 ++
 net/ipv4/devinet.c             | 64 +++++++++++++++++++++++++++---------------
 net/ipv4/ipmr.c                | 12 ++++----
 net/ipv6/addrconf.c            | 53 +++++++++++++++++++++++-----------
 net/ipv6/ip6mr.c               |  9 +++---
 net/mpls/af_mpls.c             | 28 ++++++++++--------
 security/selinux/nlmsgtab.c    |  1 +
 9 files changed, 113 insertions(+), 64 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH net-next 1/7] rtnetlink: Add RTM_DELNETCONF
  2017-03-28 21:28 [PATCH net-next 0/7] netconf: Add support for RTM_DELNETCONF David Ahern
@ 2017-03-28 21:28 ` David Ahern
  2017-03-28 21:28 ` [PATCH net-next 2/7] net: devinet: Refactor inet_netconf_notify_devconf to take event David Ahern
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: David Ahern @ 2017-03-28 21:28 UTC (permalink / raw)
  To: netdev; +Cc: nicolas.dichtel, David Ahern

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 include/uapi/linux/rtnetlink.h | 2 ++
 security/selinux/nlmsgtab.c    | 1 +
 2 files changed, 3 insertions(+)

diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index 3dd72aee4d32..cce061382e40 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -122,6 +122,8 @@ enum {
 
 	RTM_NEWNETCONF = 80,
 #define RTM_NEWNETCONF RTM_NEWNETCONF
+	RTM_DELNETCONF,
+#define RTM_DELNETCONF RTM_DELNETCONF
 	RTM_GETNETCONF = 82,
 #define RTM_GETNETCONF RTM_GETNETCONF
 
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index 2ca9cde939d4..8e67bb4c9cab 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -69,6 +69,7 @@ static struct nlmsg_perm nlmsg_route_perms[] =
 	{ RTM_GETDCB,		NETLINK_ROUTE_SOCKET__NLMSG_READ  },
 	{ RTM_SETDCB,		NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
 	{ RTM_NEWNETCONF,	NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
+	{ RTM_DELNETCONF,	NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
 	{ RTM_GETNETCONF,	NETLINK_ROUTE_SOCKET__NLMSG_READ  },
 	{ RTM_NEWMDB,		NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
 	{ RTM_DELMDB,		NETLINK_ROUTE_SOCKET__NLMSG_WRITE  },
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 2/7] net: devinet: Refactor inet_netconf_notify_devconf to take event
  2017-03-28 21:28 [PATCH net-next 0/7] netconf: Add support for RTM_DELNETCONF David Ahern
  2017-03-28 21:28 ` [PATCH net-next 1/7] rtnetlink: Add RTM_DELNETCONF David Ahern
@ 2017-03-28 21:28 ` David Ahern
  2017-03-28 21:28 ` [PATCH net-next 3/7] net: devinet: Add support for RTM_DELNETCONF David Ahern
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: David Ahern @ 2017-03-28 21:28 UTC (permalink / raw)
  To: netdev; +Cc: nicolas.dichtel, David Ahern

Refactor inet_netconf_notify_devconf to take the event as an input arg.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 include/linux/inetdevice.h |  4 ++--
 net/ipv4/devinet.c         | 32 ++++++++++++++++++++------------
 net/ipv4/ipmr.c            | 12 +++++++-----
 3 files changed, 29 insertions(+), 19 deletions(-)

diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index ee971f335a8b..a2e9d6ea1349 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -153,8 +153,8 @@ struct in_ifaddr {
 int register_inetaddr_notifier(struct notifier_block *nb);
 int unregister_inetaddr_notifier(struct notifier_block *nb);
 
-void inet_netconf_notify_devconf(struct net *net, int type, int ifindex,
-				 struct ipv4_devconf *devconf);
+void inet_netconf_notify_devconf(struct net *net, int event, int type,
+				 int ifindex, struct ipv4_devconf *devconf);
 
 struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref);
 static inline struct net_device *ip_dev_find(struct net *net, __be32 addr)
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 927f1d4b8c80..fd3218cd1870 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1831,8 +1831,8 @@ static int inet_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
 	return -EMSGSIZE;
 }
 
-void inet_netconf_notify_devconf(struct net *net, int type, int ifindex,
-				 struct ipv4_devconf *devconf)
+void inet_netconf_notify_devconf(struct net *net, int event, int type,
+				 int ifindex, struct ipv4_devconf *devconf)
 {
 	struct sk_buff *skb;
 	int err = -ENOBUFS;
@@ -1842,7 +1842,7 @@ void inet_netconf_notify_devconf(struct net *net, int type, int ifindex,
 		goto errout;
 
 	err = inet_netconf_fill_devconf(skb, ifindex, devconf, 0, 0,
-					RTM_NEWNETCONF, 0, type);
+					event, 0, type);
 	if (err < 0) {
 		/* -EMSGSIZE implies BUG in inet_netconf_msgsize_devconf() */
 		WARN_ON(err == -EMSGSIZE);
@@ -2021,10 +2021,12 @@ static void inet_forward_change(struct net *net)
 
 	IPV4_DEVCONF_ALL(net, ACCEPT_REDIRECTS) = !on;
 	IPV4_DEVCONF_DFLT(net, FORWARDING) = on;
-	inet_netconf_notify_devconf(net, NETCONFA_FORWARDING,
+	inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
+				    NETCONFA_FORWARDING,
 				    NETCONFA_IFINDEX_ALL,
 				    net->ipv4.devconf_all);
-	inet_netconf_notify_devconf(net, NETCONFA_FORWARDING,
+	inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
+				    NETCONFA_FORWARDING,
 				    NETCONFA_IFINDEX_DEFAULT,
 				    net->ipv4.devconf_dflt);
 
@@ -2037,7 +2039,8 @@ static void inet_forward_change(struct net *net)
 		in_dev = __in_dev_get_rtnl(dev);
 		if (in_dev) {
 			IN_DEV_CONF_SET(in_dev, FORWARDING, on);
-			inet_netconf_notify_devconf(net, NETCONFA_FORWARDING,
+			inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
+						    NETCONFA_FORWARDING,
 						    dev->ifindex, &in_dev->cnf);
 		}
 	}
@@ -2082,19 +2085,22 @@ static int devinet_conf_proc(struct ctl_table *ctl, int write,
 		if (i == IPV4_DEVCONF_RP_FILTER - 1 &&
 		    new_value != old_value) {
 			ifindex = devinet_conf_ifindex(net, cnf);
-			inet_netconf_notify_devconf(net, NETCONFA_RP_FILTER,
+			inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
+						    NETCONFA_RP_FILTER,
 						    ifindex, cnf);
 		}
 		if (i == IPV4_DEVCONF_PROXY_ARP - 1 &&
 		    new_value != old_value) {
 			ifindex = devinet_conf_ifindex(net, cnf);
-			inet_netconf_notify_devconf(net, NETCONFA_PROXY_NEIGH,
+			inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
+						    NETCONFA_PROXY_NEIGH,
 						    ifindex, cnf);
 		}
 		if (i == IPV4_DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN - 1 &&
 		    new_value != old_value) {
 			ifindex = devinet_conf_ifindex(net, cnf);
-			inet_netconf_notify_devconf(net, NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
+			inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
+						    NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
 						    ifindex, cnf);
 		}
 	}
@@ -2129,7 +2135,7 @@ static int devinet_sysctl_forward(struct ctl_table *ctl, int write,
 					container_of(cnf, struct in_device, cnf);
 				if (*valp)
 					dev_disable_lro(idev->dev);
-				inet_netconf_notify_devconf(net,
+				inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
 							    NETCONFA_FORWARDING,
 							    idev->dev->ifindex,
 							    cnf);
@@ -2137,7 +2143,8 @@ static int devinet_sysctl_forward(struct ctl_table *ctl, int write,
 			rtnl_unlock();
 			rt_cache_flush(net);
 		} else
-			inet_netconf_notify_devconf(net, NETCONFA_FORWARDING,
+			inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
+						    NETCONFA_FORWARDING,
 						    NETCONFA_IFINDEX_DEFAULT,
 						    net->ipv4.devconf_dflt);
 	}
@@ -2259,7 +2266,8 @@ static int __devinet_sysctl_register(struct net *net, char *dev_name,
 
 	p->sysctl = t;
 
-	inet_netconf_notify_devconf(net, NETCONFA_ALL, ifindex, p);
+	inet_netconf_notify_devconf(net, RTM_NEWNETCONF, NETCONFA_ALL,
+				    ifindex, p);
 	return 0;
 
 free:
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index c0317c940bcd..5bca64fc71b7 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -631,7 +631,7 @@ static int vif_delete(struct mr_table *mrt, int vifi, int notify,
 	in_dev = __in_dev_get_rtnl(dev);
 	if (in_dev) {
 		IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)--;
-		inet_netconf_notify_devconf(dev_net(dev),
+		inet_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF,
 					    NETCONFA_MC_FORWARDING,
 					    dev->ifindex, &in_dev->cnf);
 		ip_rt_multicast_event(in_dev);
@@ -820,8 +820,8 @@ static int vif_add(struct net *net, struct mr_table *mrt,
 		return -EADDRNOTAVAIL;
 	}
 	IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++;
-	inet_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING, dev->ifindex,
-				    &in_dev->cnf);
+	inet_netconf_notify_devconf(net, RTM_NEWNETCONF, NETCONFA_MC_FORWARDING,
+				    dev->ifindex, &in_dev->cnf);
 	ip_rt_multicast_event(in_dev);
 
 	/* Fill in the VIF structures */
@@ -1282,7 +1282,8 @@ static void mrtsock_destruct(struct sock *sk)
 	ipmr_for_each_table(mrt, net) {
 		if (sk == rtnl_dereference(mrt->mroute_sk)) {
 			IPV4_DEVCONF_ALL(net, MC_FORWARDING)--;
-			inet_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING,
+			inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
+						    NETCONFA_MC_FORWARDING,
 						    NETCONFA_IFINDEX_ALL,
 						    net->ipv4.devconf_all);
 			RCU_INIT_POINTER(mrt->mroute_sk, NULL);
@@ -1344,7 +1345,8 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval,
 		if (ret == 0) {
 			rcu_assign_pointer(mrt->mroute_sk, sk);
 			IPV4_DEVCONF_ALL(net, MC_FORWARDING)++;
-			inet_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING,
+			inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
+						    NETCONFA_MC_FORWARDING,
 						    NETCONFA_IFINDEX_ALL,
 						    net->ipv4.devconf_all);
 		}
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 3/7] net: devinet: Add support for RTM_DELNETCONF
  2017-03-28 21:28 [PATCH net-next 0/7] netconf: Add support for RTM_DELNETCONF David Ahern
  2017-03-28 21:28 ` [PATCH net-next 1/7] rtnetlink: Add RTM_DELNETCONF David Ahern
  2017-03-28 21:28 ` [PATCH net-next 2/7] net: devinet: Refactor inet_netconf_notify_devconf to take event David Ahern
@ 2017-03-28 21:28 ` David Ahern
  2017-03-28 21:28 ` [PATCH net-next 4/7] net: ipv6: Refactor inet6_netconf_notify_devconf to take event David Ahern
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: David Ahern @ 2017-03-28 21:28 UTC (permalink / raw)
  To: netdev; +Cc: nicolas.dichtel, David Ahern

Send RTM_DELNETCONF notifications when a device is deleted. The message only
needs the device index, so modify inet_netconf_fill_devconf to skip devconf
references if it is NULL.

Allows a userspace cache to remove entries as devices are deleted.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 net/ipv4/devinet.c | 32 +++++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index fd3218cd1870..6d3602ec640c 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1802,6 +1802,9 @@ static int inet_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
 	if (nla_put_s32(skb, NETCONFA_IFINDEX, ifindex) < 0)
 		goto nla_put_failure;
 
+	if (!devconf)
+		goto out;
+
 	if ((all || type == NETCONFA_FORWARDING) &&
 	    nla_put_s32(skb, NETCONFA_FORWARDING,
 			IPV4_DEVCONF(*devconf, FORWARDING)) < 0)
@@ -1823,6 +1826,7 @@ static int inet_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
 			IPV4_DEVCONF(*devconf, IGNORE_ROUTES_WITH_LINKDOWN)) < 0)
 		goto nla_put_failure;
 
+out:
 	nlmsg_end(skb, nlh);
 	return 0;
 
@@ -2276,16 +2280,18 @@ static int __devinet_sysctl_register(struct net *net, char *dev_name,
 	return -ENOBUFS;
 }
 
-static void __devinet_sysctl_unregister(struct ipv4_devconf *cnf)
+static void __devinet_sysctl_unregister(struct net *net,
+					struct ipv4_devconf *cnf, int ifindex)
 {
 	struct devinet_sysctl_table *t = cnf->sysctl;
 
-	if (!t)
-		return;
+	if (t) {
+		cnf->sysctl = NULL;
+		unregister_net_sysctl_table(t->sysctl_header);
+		kfree(t);
+	}
 
-	cnf->sysctl = NULL;
-	unregister_net_sysctl_table(t->sysctl_header);
-	kfree(t);
+	inet_netconf_notify_devconf(net, RTM_DELNETCONF, 0, ifindex, NULL);
 }
 
 static int devinet_sysctl_register(struct in_device *idev)
@@ -2307,7 +2313,9 @@ static int devinet_sysctl_register(struct in_device *idev)
 
 static void devinet_sysctl_unregister(struct in_device *idev)
 {
-	__devinet_sysctl_unregister(&idev->cnf);
+	struct net *net = dev_net(idev->dev);
+
+	__devinet_sysctl_unregister(net, &idev->cnf, idev->dev->ifindex);
 	neigh_sysctl_unregister(idev->arp_parms);
 }
 
@@ -2382,9 +2390,9 @@ static __net_init int devinet_init_net(struct net *net)
 
 #ifdef CONFIG_SYSCTL
 err_reg_ctl:
-	__devinet_sysctl_unregister(dflt);
+	__devinet_sysctl_unregister(net, dflt, NETCONFA_IFINDEX_DEFAULT);
 err_reg_dflt:
-	__devinet_sysctl_unregister(all);
+	__devinet_sysctl_unregister(net, all, NETCONFA_IFINDEX_ALL);
 err_reg_all:
 	if (tbl != ctl_forward_entry)
 		kfree(tbl);
@@ -2406,8 +2414,10 @@ static __net_exit void devinet_exit_net(struct net *net)
 
 	tbl = net->ipv4.forw_hdr->ctl_table_arg;
 	unregister_net_sysctl_table(net->ipv4.forw_hdr);
-	__devinet_sysctl_unregister(net->ipv4.devconf_dflt);
-	__devinet_sysctl_unregister(net->ipv4.devconf_all);
+	__devinet_sysctl_unregister(net, net->ipv4.devconf_dflt,
+				    NETCONFA_IFINDEX_DEFAULT);
+	__devinet_sysctl_unregister(net, net->ipv4.devconf_all,
+				    NETCONFA_IFINDEX_ALL);
 	kfree(tbl);
 #endif
 	kfree(net->ipv4.devconf_dflt);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 4/7] net: ipv6: Refactor inet6_netconf_notify_devconf to take event
  2017-03-28 21:28 [PATCH net-next 0/7] netconf: Add support for RTM_DELNETCONF David Ahern
                   ` (2 preceding siblings ...)
  2017-03-28 21:28 ` [PATCH net-next 3/7] net: devinet: Add support for RTM_DELNETCONF David Ahern
@ 2017-03-28 21:28 ` David Ahern
  2017-03-28 21:28 ` [PATCH net-next 5/7] net: ipv6: Add support for RTM_DELNETCONF David Ahern
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: David Ahern @ 2017-03-28 21:28 UTC (permalink / raw)
  To: netdev; +Cc: nicolas.dichtel, David Ahern

Refactor inet6_netconf_notify_devconf to take the event as an input arg.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 include/net/addrconf.h |  4 ++--
 net/ipv6/addrconf.c    | 33 ++++++++++++++++++++++-----------
 net/ipv6/ip6mr.c       |  9 +++++----
 3 files changed, 29 insertions(+), 17 deletions(-)

diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 17c6fd84e287..1aeb25dd42a7 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -262,8 +262,8 @@ int register_inet6addr_notifier(struct notifier_block *nb);
 int unregister_inet6addr_notifier(struct notifier_block *nb);
 int inet6addr_notifier_call_chain(unsigned long val, void *v);
 
-void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex,
-				  struct ipv6_devconf *devconf);
+void inet6_netconf_notify_devconf(struct net *net, int event, int type,
+				  int ifindex, struct ipv6_devconf *devconf);
 
 /**
  * __in6_dev_get - get inet6_dev pointer from netdevice
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index dff5beb26a01..b8442be85e1b 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -575,8 +575,8 @@ static int inet6_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
 	return -EMSGSIZE;
 }
 
-void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex,
-				  struct ipv6_devconf *devconf)
+void inet6_netconf_notify_devconf(struct net *net, int event, int type,
+				  int ifindex, struct ipv6_devconf *devconf)
 {
 	struct sk_buff *skb;
 	int err = -ENOBUFS;
@@ -586,7 +586,7 @@ void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex,
 		goto errout;
 
 	err = inet6_netconf_fill_devconf(skb, ifindex, devconf, 0, 0,
-					 RTM_NEWNETCONF, 0, type);
+					 event, 0, type);
 	if (err < 0) {
 		/* -EMSGSIZE implies BUG in inet6_netconf_msgsize_devconf() */
 		WARN_ON(err == -EMSGSIZE);
@@ -769,7 +769,8 @@ static void dev_forward_change(struct inet6_dev *idev)
 		else
 			addrconf_leave_anycast(ifa);
 	}
-	inet6_netconf_notify_devconf(dev_net(dev), NETCONFA_FORWARDING,
+	inet6_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF,
+				     NETCONFA_FORWARDING,
 				     dev->ifindex, &idev->cnf);
 }
 
@@ -804,7 +805,8 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf)
 
 	if (p == &net->ipv6.devconf_dflt->forwarding) {
 		if ((!newf) ^ (!old))
-			inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING,
+			inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
+						     NETCONFA_FORWARDING,
 						     NETCONFA_IFINDEX_DEFAULT,
 						     net->ipv6.devconf_dflt);
 		rtnl_unlock();
@@ -816,13 +818,15 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf)
 
 		net->ipv6.devconf_dflt->forwarding = newf;
 		if ((!newf) ^ (!old_dflt))
-			inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING,
+			inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
+						     NETCONFA_FORWARDING,
 						     NETCONFA_IFINDEX_DEFAULT,
 						     net->ipv6.devconf_dflt);
 
 		addrconf_forward_change(net, newf);
 		if ((!newf) ^ (!old))
-			inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING,
+			inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
+						     NETCONFA_FORWARDING,
 						     NETCONFA_IFINDEX_ALL,
 						     net->ipv6.devconf_all);
 	} else if ((!newf) ^ (!old))
@@ -847,6 +851,7 @@ static void addrconf_linkdown_change(struct net *net, __s32 newf)
 			idev->cnf.ignore_routes_with_linkdown = newf;
 			if (changed)
 				inet6_netconf_notify_devconf(dev_net(dev),
+							     RTM_NEWNETCONF,
 							     NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
 							     dev->ifindex,
 							     &idev->cnf);
@@ -869,6 +874,7 @@ static int addrconf_fixup_linkdown(struct ctl_table *table, int *p, int newf)
 	if (p == &net->ipv6.devconf_dflt->ignore_routes_with_linkdown) {
 		if ((!newf) ^ (!old))
 			inet6_netconf_notify_devconf(net,
+						     RTM_NEWNETCONF,
 						     NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
 						     NETCONFA_IFINDEX_DEFAULT,
 						     net->ipv6.devconf_dflt);
@@ -881,6 +887,7 @@ static int addrconf_fixup_linkdown(struct ctl_table *table, int *p, int newf)
 		addrconf_linkdown_change(net, newf);
 		if ((!newf) ^ (!old))
 			inet6_netconf_notify_devconf(net,
+						     RTM_NEWNETCONF,
 						     NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
 						     NETCONFA_IFINDEX_ALL,
 						     net->ipv6.devconf_all);
@@ -5675,17 +5682,20 @@ int addrconf_sysctl_proxy_ndp(struct ctl_table *ctl, int write,
 			return restart_syscall();
 
 		if (valp == &net->ipv6.devconf_dflt->proxy_ndp)
-			inet6_netconf_notify_devconf(net, NETCONFA_PROXY_NEIGH,
+			inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
+						     NETCONFA_PROXY_NEIGH,
 						     NETCONFA_IFINDEX_DEFAULT,
 						     net->ipv6.devconf_dflt);
 		else if (valp == &net->ipv6.devconf_all->proxy_ndp)
-			inet6_netconf_notify_devconf(net, NETCONFA_PROXY_NEIGH,
+			inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
+						     NETCONFA_PROXY_NEIGH,
 						     NETCONFA_IFINDEX_ALL,
 						     net->ipv6.devconf_all);
 		else {
 			struct inet6_dev *idev = ctl->extra1;
 
-			inet6_netconf_notify_devconf(net, NETCONFA_PROXY_NEIGH,
+			inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
+						     NETCONFA_PROXY_NEIGH,
 						     idev->dev->ifindex,
 						     &idev->cnf);
 		}
@@ -6348,7 +6358,8 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name,
 		ifindex = NETCONFA_IFINDEX_DEFAULT;
 	else
 		ifindex = idev->dev->ifindex;
-	inet6_netconf_notify_devconf(net, NETCONFA_ALL, ifindex, p);
+	inet6_netconf_notify_devconf(net, RTM_NEWNETCONF, NETCONFA_ALL,
+				     ifindex, p);
 	return 0;
 
 free:
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 6ba6c900ebcf..fb4546e80c82 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -815,7 +815,7 @@ static int mif6_delete(struct mr6_table *mrt, int vifi, struct list_head *head)
 	in6_dev = __in6_dev_get(dev);
 	if (in6_dev) {
 		in6_dev->cnf.mc_forwarding--;
-		inet6_netconf_notify_devconf(dev_net(dev),
+		inet6_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF,
 					     NETCONFA_MC_FORWARDING,
 					     dev->ifindex, &in6_dev->cnf);
 	}
@@ -974,7 +974,7 @@ static int mif6_add(struct net *net, struct mr6_table *mrt,
 	in6_dev = __in6_dev_get(dev);
 	if (in6_dev) {
 		in6_dev->cnf.mc_forwarding++;
-		inet6_netconf_notify_devconf(dev_net(dev),
+		inet6_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF,
 					     NETCONFA_MC_FORWARDING,
 					     dev->ifindex, &in6_dev->cnf);
 	}
@@ -1599,7 +1599,8 @@ static int ip6mr_sk_init(struct mr6_table *mrt, struct sock *sk)
 	write_unlock_bh(&mrt_lock);
 
 	if (!err)
-		inet6_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING,
+		inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
+					     NETCONFA_MC_FORWARDING,
 					     NETCONFA_IFINDEX_ALL,
 					     net->ipv6.devconf_all);
 	rtnl_unlock();
@@ -1620,7 +1621,7 @@ int ip6mr_sk_done(struct sock *sk)
 			mrt->mroute6_sk = NULL;
 			net->ipv6.devconf_all->mc_forwarding--;
 			write_unlock_bh(&mrt_lock);
-			inet6_netconf_notify_devconf(net,
+			inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
 						     NETCONFA_MC_FORWARDING,
 						     NETCONFA_IFINDEX_ALL,
 						     net->ipv6.devconf_all);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 5/7] net: ipv6: Add support for RTM_DELNETCONF
  2017-03-28 21:28 [PATCH net-next 0/7] netconf: Add support for RTM_DELNETCONF David Ahern
                   ` (3 preceding siblings ...)
  2017-03-28 21:28 ` [PATCH net-next 4/7] net: ipv6: Refactor inet6_netconf_notify_devconf to take event David Ahern
@ 2017-03-28 21:28 ` David Ahern
  2017-03-28 21:28 ` [PATCH net-next 6/7] net:mpls: Refactor mpls_netconf_notify_devconf to take event David Ahern
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: David Ahern @ 2017-03-28 21:28 UTC (permalink / raw)
  To: netdev; +Cc: nicolas.dichtel, David Ahern

Send RTM_DELNETCONF notifications when a device is deleted. The message only
needs the device index, so modify inet6_netconf_fill_devconf to skip devconf
references if it is NULL.

Allows a userspace cache to remove entries as devices are deleted.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 net/ipv6/addrconf.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index b8442be85e1b..67ec87ea5fb6 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -549,6 +549,9 @@ static int inet6_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
 	if (nla_put_s32(skb, NETCONFA_IFINDEX, ifindex) < 0)
 		goto nla_put_failure;
 
+	if (!devconf)
+		goto out;
+
 	if ((all || type == NETCONFA_FORWARDING) &&
 	    nla_put_s32(skb, NETCONFA_FORWARDING, devconf->forwarding) < 0)
 		goto nla_put_failure;
@@ -567,6 +570,7 @@ static int inet6_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
 			devconf->ignore_routes_with_linkdown) < 0)
 		goto nla_put_failure;
 
+out:
 	nlmsg_end(skb, nlh);
 	return 0;
 
@@ -6368,7 +6372,8 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name,
 	return -ENOBUFS;
 }
 
-static void __addrconf_sysctl_unregister(struct ipv6_devconf *p)
+static void __addrconf_sysctl_unregister(struct net *net,
+					 struct ipv6_devconf *p, int ifindex)
 {
 	struct ctl_table *table;
 
@@ -6379,6 +6384,8 @@ static void __addrconf_sysctl_unregister(struct ipv6_devconf *p)
 	unregister_net_sysctl_table(p->sysctl_header);
 	p->sysctl_header = NULL;
 	kfree(table);
+
+	inet6_netconf_notify_devconf(net, RTM_DELNETCONF, 0, ifindex, NULL);
 }
 
 static int addrconf_sysctl_register(struct inet6_dev *idev)
@@ -6402,7 +6409,8 @@ static int addrconf_sysctl_register(struct inet6_dev *idev)
 
 static void addrconf_sysctl_unregister(struct inet6_dev *idev)
 {
-	__addrconf_sysctl_unregister(&idev->cnf);
+	__addrconf_sysctl_unregister(dev_net(idev->dev), &idev->cnf,
+				     idev->dev->ifindex);
 	neigh_sysctl_unregister(idev->nd_parms);
 }
 
@@ -6445,7 +6453,7 @@ static int __net_init addrconf_init_net(struct net *net)
 
 #ifdef CONFIG_SYSCTL
 err_reg_dflt:
-	__addrconf_sysctl_unregister(all);
+	__addrconf_sysctl_unregister(net, all, NETCONFA_IFINDEX_ALL);
 err_reg_all:
 	kfree(dflt);
 #endif
@@ -6458,8 +6466,10 @@ static int __net_init addrconf_init_net(struct net *net)
 static void __net_exit addrconf_exit_net(struct net *net)
 {
 #ifdef CONFIG_SYSCTL
-	__addrconf_sysctl_unregister(net->ipv6.devconf_dflt);
-	__addrconf_sysctl_unregister(net->ipv6.devconf_all);
+	__addrconf_sysctl_unregister(net, net->ipv6.devconf_dflt,
+				     NETCONFA_IFINDEX_DEFAULT);
+	__addrconf_sysctl_unregister(net, net->ipv6.devconf_all,
+				     NETCONFA_IFINDEX_ALL);
 #endif
 	kfree(net->ipv6.devconf_dflt);
 	kfree(net->ipv6.devconf_all);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 6/7] net:mpls: Refactor mpls_netconf_notify_devconf to take event
  2017-03-28 21:28 [PATCH net-next 0/7] netconf: Add support for RTM_DELNETCONF David Ahern
                   ` (4 preceding siblings ...)
  2017-03-28 21:28 ` [PATCH net-next 5/7] net: ipv6: Add support for RTM_DELNETCONF David Ahern
@ 2017-03-28 21:28 ` David Ahern
  2017-03-28 21:28 ` [PATCH net-next 7/7] net: mpls: Send netconf messages on device register and unregister David Ahern
  2017-03-29  5:32 ` [PATCH net-next 0/7] netconf: Add support for RTM_DELNETCONF David Miller
  7 siblings, 0 replies; 12+ messages in thread
From: David Ahern @ 2017-03-28 21:28 UTC (permalink / raw)
  To: netdev; +Cc: nicolas.dichtel, David Ahern

Refactor mpls_netconf_notify_devconf to take the event as an input arg.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 net/mpls/af_mpls.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index 74755920c689..313cd0a93a63 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -1040,8 +1040,8 @@ static int mpls_netconf_msgsize_devconf(int type)
 	return size;
 }
 
-static void mpls_netconf_notify_devconf(struct net *net, int type,
-					struct mpls_dev *mdev)
+static void mpls_netconf_notify_devconf(struct net *net, int event,
+					int type, struct mpls_dev *mdev)
 {
 	struct sk_buff *skb;
 	int err = -ENOBUFS;
@@ -1050,8 +1050,7 @@ static void mpls_netconf_notify_devconf(struct net *net, int type,
 	if (!skb)
 		goto errout;
 
-	err = mpls_netconf_fill_devconf(skb, mdev, 0, 0, RTM_NEWNETCONF,
-					0, type);
+	err = mpls_netconf_fill_devconf(skb, mdev, 0, 0, event, 0, type);
 	if (err < 0) {
 		/* -EMSGSIZE implies BUG in mpls_netconf_msgsize_devconf() */
 		WARN_ON(err == -EMSGSIZE);
@@ -1184,9 +1183,8 @@ static int mpls_conf_proc(struct ctl_table *ctl, int write,
 
 		if (i == offsetof(struct mpls_dev, input_enabled) &&
 		    val != oval) {
-			mpls_netconf_notify_devconf(net,
-						    NETCONFA_INPUT,
-						    mdev);
+			mpls_netconf_notify_devconf(net, RTM_NEWNETCONF,
+						    NETCONFA_INPUT, mdev);
 		}
 	}
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH net-next 7/7] net: mpls: Send netconf messages on device register and unregister
  2017-03-28 21:28 [PATCH net-next 0/7] netconf: Add support for RTM_DELNETCONF David Ahern
                   ` (5 preceding siblings ...)
  2017-03-28 21:28 ` [PATCH net-next 6/7] net:mpls: Refactor mpls_netconf_notify_devconf to take event David Ahern
@ 2017-03-28 21:28 ` David Ahern
  2017-03-29  5:32 ` [PATCH net-next 0/7] netconf: Add support for RTM_DELNETCONF David Miller
  7 siblings, 0 replies; 12+ messages in thread
From: David Ahern @ 2017-03-28 21:28 UTC (permalink / raw)
  To: netdev; +Cc: nicolas.dichtel, David Ahern

Send netconf notifications for MPLS when the device registers and
unregisters.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 net/mpls/af_mpls.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index 313cd0a93a63..673f3d990b5c 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -1225,10 +1225,11 @@ static int mpls_dev_sysctl_register(struct net_device *dev,
 
 	snprintf(path, sizeof(path), "net/mpls/conf/%s", dev->name);
 
-	mdev->sysctl = register_net_sysctl(dev_net(dev), path, table);
+	mdev->sysctl = register_net_sysctl(net, path, table);
 	if (!mdev->sysctl)
 		goto free;
 
+	mpls_netconf_notify_devconf(net, RTM_NEWNETCONF, NETCONFA_ALL, mdev);
 	return 0;
 
 free:
@@ -1237,13 +1238,17 @@ static int mpls_dev_sysctl_register(struct net_device *dev,
 	return -ENOBUFS;
 }
 
-static void mpls_dev_sysctl_unregister(struct mpls_dev *mdev)
+static void mpls_dev_sysctl_unregister(struct net_device *dev,
+				       struct mpls_dev *mdev)
 {
+	struct net *net = dev_net(dev);
 	struct ctl_table *table;
 
 	table = mdev->sysctl->ctl_table_arg;
 	unregister_net_sysctl_table(mdev->sysctl);
 	kfree(table);
+
+	mpls_netconf_notify_devconf(net, RTM_DELNETCONF, 0, mdev);
 }
 
 static struct mpls_dev *mpls_add_dev(struct net_device *dev)
@@ -1269,11 +1274,12 @@ static struct mpls_dev *mpls_add_dev(struct net_device *dev)
 		u64_stats_init(&mpls_stats->syncp);
 	}
 
+	mdev->dev = dev;
+
 	err = mpls_dev_sysctl_register(dev, mdev);
 	if (err)
 		goto free;
 
-	mdev->dev = dev;
 	rcu_assign_pointer(dev->mpls_ptr, mdev);
 
 	return mdev;
@@ -1419,7 +1425,7 @@ static int mpls_dev_notify(struct notifier_block *this, unsigned long event,
 		mpls_ifdown(dev, event);
 		mdev = mpls_dev_get(dev);
 		if (mdev) {
-			mpls_dev_sysctl_unregister(mdev);
+			mpls_dev_sysctl_unregister(dev, mdev);
 			RCU_INIT_POINTER(dev->mpls_ptr, NULL);
 			call_rcu(&mdev->rcu, mpls_dev_destroy_rcu);
 		}
@@ -1429,7 +1435,7 @@ static int mpls_dev_notify(struct notifier_block *this, unsigned long event,
 		if (mdev) {
 			int err;
 
-			mpls_dev_sysctl_unregister(mdev);
+			mpls_dev_sysctl_unregister(dev, mdev);
 			err = mpls_dev_sysctl_register(dev, mdev);
 			if (err)
 				return notifier_from_errno(err);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 0/7] netconf: Add support for RTM_DELNETCONF
  2017-03-28 21:28 [PATCH net-next 0/7] netconf: Add support for RTM_DELNETCONF David Ahern
                   ` (6 preceding siblings ...)
  2017-03-28 21:28 ` [PATCH net-next 7/7] net: mpls: Send netconf messages on device register and unregister David Ahern
@ 2017-03-29  5:32 ` David Miller
  2017-03-29  9:36   ` Nicolas Dichtel
  7 siblings, 1 reply; 12+ messages in thread
From: David Miller @ 2017-03-29  5:32 UTC (permalink / raw)
  To: dsa; +Cc: netdev, nicolas.dichtel

From: David Ahern <dsa@cumulusnetworks.com>
Date: Tue, 28 Mar 2017 14:28:00 -0700

> netconf notifications are sent as devices register but not when they
> are deleted leaving userspace caches out of sync. Add support for
> RTM_DELNETCONF to ipv4, ipv6 and mpls.
> 
> MPLS is missing RTM_NEWNETCONF as devices are created, so add it as well.

Series applied, thanks.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 0/7] netconf: Add support for RTM_DELNETCONF
  2017-03-29  5:32 ` [PATCH net-next 0/7] netconf: Add support for RTM_DELNETCONF David Miller
@ 2017-03-29  9:36   ` Nicolas Dichtel
  2017-03-29 14:13     ` David Ahern
  0 siblings, 1 reply; 12+ messages in thread
From: Nicolas Dichtel @ 2017-03-29  9:36 UTC (permalink / raw)
  To: David Miller, dsa; +Cc: netdev

Le 29/03/2017 à 07:32, David Miller a écrit :
> From: David Ahern <dsa@cumulusnetworks.com>
> Date: Tue, 28 Mar 2017 14:28:00 -0700
> 
>> netconf notifications are sent as devices register but not when they
>> are deleted leaving userspace caches out of sync. Add support for
>> RTM_DELNETCONF to ipv4, ipv6 and mpls.
Not sure why those notifications are needed. When an interface is set down, ipv4
route deletion are not notified. Why is it needed for netconf?

>>
>> MPLS is missing RTM_NEWNETCONF as devices are created, so add it as well.
> 
> Series applied, thanks.
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 0/7] netconf: Add support for RTM_DELNETCONF
  2017-03-29  9:36   ` Nicolas Dichtel
@ 2017-03-29 14:13     ` David Ahern
  2017-03-29 14:22       ` Nicolas Dichtel
  0 siblings, 1 reply; 12+ messages in thread
From: David Ahern @ 2017-03-29 14:13 UTC (permalink / raw)
  To: nicolas.dichtel, David Miller; +Cc: netdev

On 3/29/17 3:36 AM, Nicolas Dichtel wrote:
> Le 29/03/2017 à 07:32, David Miller a écrit :
>> From: David Ahern <dsa@cumulusnetworks.com>
>> Date: Tue, 28 Mar 2017 14:28:00 -0700
>>
>>> netconf notifications are sent as devices register but not when they
>>> are deleted leaving userspace caches out of sync. Add support for
>>> RTM_DELNETCONF to ipv4, ipv6 and mpls.
> Not sure why those notifications are needed. When an interface is set down, ipv4
> route deletion are not notified. Why is it needed for netconf?
> 

We carry a patch to send notifications for route deletes. In general, it
makes management of libnl caches much easier when delete notifications
are sent for each type. Without it, a link delete requires walking the
other caches removing objects.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH net-next 0/7] netconf: Add support for RTM_DELNETCONF
  2017-03-29 14:13     ` David Ahern
@ 2017-03-29 14:22       ` Nicolas Dichtel
  0 siblings, 0 replies; 12+ messages in thread
From: Nicolas Dichtel @ 2017-03-29 14:22 UTC (permalink / raw)
  To: David Ahern, David Miller; +Cc: netdev

Le 29/03/2017 à 16:13, David Ahern a écrit :
> On 3/29/17 3:36 AM, Nicolas Dichtel wrote:
>> Le 29/03/2017 à 07:32, David Miller a écrit :
>>> From: David Ahern <dsa@cumulusnetworks.com>
>>> Date: Tue, 28 Mar 2017 14:28:00 -0700
>>>
>>>> netconf notifications are sent as devices register but not when they
>>>> are deleted leaving userspace caches out of sync. Add support for
>>>> RTM_DELNETCONF to ipv4, ipv6 and mpls.
>> Not sure why those notifications are needed. When an interface is set down, ipv4
>> route deletion are not notified. Why is it needed for netconf?
>>
> 
> We carry a patch to send notifications for route deletes. In general, it
> makes management of libnl caches much easier when delete notifications
> are sent for each type. Without it, a link delete requires walking the
> other caches removing objects.
> 
David rejected this kind of patch several times, but maybe he changed his mind.

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2017-03-29 14:22 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-28 21:28 [PATCH net-next 0/7] netconf: Add support for RTM_DELNETCONF David Ahern
2017-03-28 21:28 ` [PATCH net-next 1/7] rtnetlink: Add RTM_DELNETCONF David Ahern
2017-03-28 21:28 ` [PATCH net-next 2/7] net: devinet: Refactor inet_netconf_notify_devconf to take event David Ahern
2017-03-28 21:28 ` [PATCH net-next 3/7] net: devinet: Add support for RTM_DELNETCONF David Ahern
2017-03-28 21:28 ` [PATCH net-next 4/7] net: ipv6: Refactor inet6_netconf_notify_devconf to take event David Ahern
2017-03-28 21:28 ` [PATCH net-next 5/7] net: ipv6: Add support for RTM_DELNETCONF David Ahern
2017-03-28 21:28 ` [PATCH net-next 6/7] net:mpls: Refactor mpls_netconf_notify_devconf to take event David Ahern
2017-03-28 21:28 ` [PATCH net-next 7/7] net: mpls: Send netconf messages on device register and unregister David Ahern
2017-03-29  5:32 ` [PATCH net-next 0/7] netconf: Add support for RTM_DELNETCONF David Miller
2017-03-29  9:36   ` Nicolas Dichtel
2017-03-29 14:13     ` David Ahern
2017-03-29 14:22       ` Nicolas Dichtel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.