netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sabrina Dubroca <sd@queasysnail.net>
To: Antonio Quartulli <antonio@openvpn.net>
Cc: netdev@vger.kernel.org, Jakub Kicinski <kuba@kernel.org>,
	Sergey Ryazanov <ryazanov.s.a@gmail.com>,
	Paolo Abeni <pabeni@redhat.com>,
	Eric Dumazet <edumazet@google.com>, Andrew Lunn <andrew@lunn.ch>,
	Esben Haabendal <esben@geanix.com>
Subject: Re: [PATCH net-next v3 04/24] ovpn: add basic interface creation/destruction/management routines
Date: Thu, 9 May 2024 14:16:12 +0200	[thread overview]
Message-ID: <Zjy-jPqyKo-6clve@hog> (raw)
In-Reply-To: <1d31ca80-055e-4601-91b6-b0dc38b721c7@openvpn.net>

2024-05-09, 12:35:32 +0200, Antonio Quartulli wrote:
> On 09/05/2024 12:09, Sabrina Dubroca wrote:
> > 2024-05-09, 10:25:44 +0200, Antonio Quartulli wrote:
> > > On 08/05/2024 16:52, Sabrina Dubroca wrote:
> > > > 2024-05-06, 03:16:17 +0200, Antonio Quartulli wrote:
> > > > >    static int ovpn_netdev_notifier_call(struct notifier_block *nb,
> > > > >    				     unsigned long state, void *ptr)
> > > > >    {
> > > > >    	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
> > > > > +	struct ovpn_struct *ovpn;
> > > > >    	if (!ovpn_dev_is_valid(dev))
> > > > >    		return NOTIFY_DONE;
> > > > > +	ovpn = netdev_priv(dev);
> > > > > +
> > > > >    	switch (state) {
> > > > >    	case NETDEV_REGISTER:
> > > > > -		/* add device to internal list for later destruction upon
> > > > > -		 * unregistration
> > > > > -		 */
> > > > > +		ovpn->registered = true;
> > > > >    		break;
> > > > >    	case NETDEV_UNREGISTER:
> > > > > +		/* twiddle thumbs on netns device moves */
> > > > > +		if (dev->reg_state != NETREG_UNREGISTERING)
> > > > > +			break;
> > > > > +
> > > > >    		/* can be delivered multiple times, so check registered flag,
> > > > >    		 * then destroy the interface
> > > > >    		 */
> > > > > +		if (!ovpn->registered)
> > > > > +			return NOTIFY_DONE;
> > > > > +
> > > > > +		ovpn_iface_destruct(ovpn);
> > > > 
> > > > Maybe I'm misunderstanding this code. Why do you want to manually
> > > > destroy a device that is already going away?
> > > 
> > > We need to perform some internal cleanup (i.e. release all peers).
> > > I don't see how this can happen automatically, no?
> > 
> > That's what ->priv_destructor does,
> 
> Not really.
> 
> Every peer object increases the netdev refcounter to the netdev, therefore
> we must first delete all peers in order to have netdevice->refcnt reach 0
> (and then invoke priv_destructor).

Oh, I see. I'm still trying to wrap my head around all the objects and
components of your driver.

> So the idea is: upon UNREGISTER event we drop all resources and eventually
> (via RCU) all references to the netdev are also released, which in turn
> triggers the destructor.
> 
> makes sense?

That part, yes, thanks for explaining. Do you really need the peers to
hold a reference on the netdevice? With my limited understanding, it
seems the peers are sub-objects of the netdevice.

> > and it will be called ultimately
> > by the unregister_netdevice call you have in ovpn_iface_destruct (in
> > netdev_run_todo). Anyway, this UNREGISTER event is probably generated
> > by unregister_netdevice_many_notify (basically a previous
> > unregister_netdevice() call), so I don't know why you want to call
> > unregister_netdevice again on the same device.
> 
> I believe I have seen this notification being triggered upon netns exit, but
> in that case the netdevice was not being removed from core.

Sure, but you have a comment about that and you're filtering that
event, so I'm ignoring this case.

> Hence I decided to fully trigger the unregistration.

That's the bit that doesn't make sense to me: the device is going
away, so you trigger a manual unregister. Cleaning up some additional
resources (peers etc), that makes sense. But calling
unregister_netdevice (when you're most likely getting called from
unregister_netdevice already, because I don't see other spots setting
dev->reg_state = NETREG_UNREGISTERING) is what I don't get. And I
wonder why you're not hitting the BUG_ON in
unregister_netdevice_many_notify:

    BUG_ON(dev->reg_state != NETREG_REGISTERED);


> > > > > @@ -62,6 +210,24 @@ static struct notifier_block ovpn_netdev_notifier = {
> > > > >    	.notifier_call = ovpn_netdev_notifier_call,
> > > > >    };
> > > > > +static void ovpn_netns_pre_exit(struct net *net)

BTW, in case you end up keeping this function, it should have
__net_exit annotation (see for example ipv4_frags_exit_net).

> > > > > +{
> > > > > +	struct ovpn_struct *ovpn;
> > > > > +
> > > > > +	rtnl_lock();
> > > > > +	list_for_each_entry(ovpn, &dev_list, dev_list) {
> > > > > +		if (dev_net(ovpn->dev) != net)
> > > > > +			continue;
> > > > > +
> > > > > +		ovpn_iface_destruct(ovpn);
> > > > 
> > > > Is this needed? On netns destruction all devices within the ns will be
> > > > destroyed by the networking core.
> > > 
> > > Before implementing ovpn_netns_pre_exit() this way, upon namespace deletion
> > > the ovpn interface was being moved to the global namespace.
> > 
> > Crap it's only the devices with ->rtnl_link_ops that get killed by the
> > core.
> 
> exactly! this goes hand to hand with my comment above: event delivered but
> interface not destroyed.

There's no event sent to ovpn_netdev_notifier_call in that case (well,
only the fake "unregister" out of the current netns that you're
ignoring). Otherwise, you wouldn't need ovpn_netns_pre_exit.

> > Because you create your devices via genl (which I'm not a fan
> > of, even if it's a bit nicer for userspace having a single netlink api
> > to deal with),
> 
> Originally I had implemented the rtnl_link_ops, but the (meaningful)
> objection was that a user is never supposed to create an ovpn iface by
> himself, but there should always be an openvpn process running in userspace.
> Hence the restriction to genl only.

Sorry, but how does genl prevent a user from creating the ovpn
interface manually? Whatever API you define, anyone who manages to
come up with the right netlink message will be able to create an
interface. You can't stop people from using your API without your
official client.

> > default_device_exit_batch/default_device_exit_net think
> > ovpn devices are real NICs and move them back to init_net instead of
> > destroying them.
> > 
> > Maybe we can extend the condition in default_device_exit_net with a
> > new flag so that ovpn devices get destroyed by the core, even without
> > rtnl_link_ops?
> 
> Thanks for pointing out the function responsible for this decision.
> How would you extend the check though?
>
> Alternatively, what if ovpn simply registers an empty rtnl_link_ops with
> netns_fund set to false? That should make the condition happy, while keeping
> ovpn genl-only

Yes. I was thinking about adding a flag to the device, because I
wasn't sure an almost empty rtnl_link_ops could be handled safely, but
it seems ok. ovs does it, see commit 5b9e7e160795 ("openvswitch:
introduce rtnl ops stub"). And, as that commit message says, "ip -d
link show" would also show that the device is of type openvpn (or
ovpn, whatever you put in ops->kind), which would be nice.

-- 
Sabrina


  reply	other threads:[~2024-05-09 12:16 UTC|newest]

Thread overview: 117+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-06  1:16 [PATCH net-next v3 00/24] Introducing OpenVPN Data Channel Offload Antonio Quartulli
2024-05-06  1:16 ` [PATCH net-next v3 01/24] netlink: add NLA_POLICY_MAX_LEN macro Antonio Quartulli
2024-05-06  1:16 ` [PATCH net-next v3 02/24] net: introduce OpenVPN Data Channel Offload (ovpn) Antonio Quartulli
2024-05-06  1:16 ` [PATCH net-next v3 03/24] ovpn: add basic netlink support Antonio Quartulli
2024-05-08  0:10   ` Jakub Kicinski
2024-05-08  7:42     ` Antonio Quartulli
2024-05-08 14:42   ` Sabrina Dubroca
2024-05-08 14:51     ` Antonio Quartulli
2024-05-06  1:16 ` [PATCH net-next v3 04/24] ovpn: add basic interface creation/destruction/management routines Antonio Quartulli
2024-05-08  0:18   ` Jakub Kicinski
2024-05-08  7:53     ` Antonio Quartulli
2024-05-08 14:52   ` Sabrina Dubroca
2024-05-09  1:06     ` Jakub Kicinski
2024-05-09  8:25     ` Antonio Quartulli
2024-05-09 10:09       ` Sabrina Dubroca
2024-05-09 10:35         ` Antonio Quartulli
2024-05-09 12:16           ` Sabrina Dubroca [this message]
2024-05-09 13:25             ` Antonio Quartulli
2024-05-09 13:52               ` Sabrina Dubroca
2024-05-06  1:16 ` [PATCH net-next v3 05/24] ovpn: implement interface creation/destruction via netlink Antonio Quartulli
2024-05-08  0:21   ` Jakub Kicinski
2024-05-08  9:49     ` Antonio Quartulli
2024-05-09  1:09       ` Jakub Kicinski
2024-05-09  8:30         ` Antonio Quartulli
2024-05-06  1:16 ` [PATCH net-next v3 06/24] ovpn: keep carrier always on Antonio Quartulli
2024-05-06  1:16 ` [PATCH net-next v3 07/24] ovpn: introduce the ovpn_peer object Antonio Quartulli
2024-05-08 16:06   ` Sabrina Dubroca
2024-05-08 20:31     ` Antonio Quartulli
2024-05-09 13:04       ` Sabrina Dubroca
2024-05-09 13:24         ` Andrew Lunn
2024-05-10 18:57           ` Antonio Quartulli
2024-05-11  0:28             ` Jakub Kicinski
2024-05-09 13:44         ` Antonio Quartulli
2024-05-09 13:55           ` Andrew Lunn
2024-05-09 14:17           ` Sabrina Dubroca
2024-05-09 14:36             ` Antonio Quartulli
2024-05-09 14:53               ` Antonio Quartulli
2024-05-10 10:30                 ` Sabrina Dubroca
2024-05-10 12:34                   ` Antonio Quartulli
2024-05-10 14:11                     ` Sabrina Dubroca
2024-05-13 10:09   ` Simon Horman
2024-05-13 10:53     ` Antonio Quartulli
2024-05-13 15:04       ` Simon Horman
2024-05-06  1:16 ` [PATCH net-next v3 08/24] ovpn: introduce the ovpn_socket object Antonio Quartulli
2024-05-08 17:10   ` Sabrina Dubroca
2024-05-08 20:38     ` Antonio Quartulli
2024-05-09 13:32       ` Sabrina Dubroca
2024-05-09 13:46         ` Antonio Quartulli
2024-05-06  1:16 ` [PATCH net-next v3 09/24] ovpn: implement basic TX path (UDP) Antonio Quartulli
2024-05-10 13:01   ` Sabrina Dubroca
2024-05-10 13:39     ` Antonio Quartulli
2024-05-12 21:35   ` Sabrina Dubroca
2024-05-13  7:37     ` Antonio Quartulli
2024-05-13  9:36       ` Sabrina Dubroca
2024-05-13  9:47         ` Antonio Quartulli
2024-05-06  1:16 ` [PATCH net-next v3 10/24] ovpn: implement basic RX " Antonio Quartulli
2024-05-10 13:45   ` Sabrina Dubroca
2024-05-10 14:41     ` Antonio Quartulli
2024-07-18 10:46       ` Sabrina Dubroca
2024-07-18 13:06         ` Antonio Quartulli
2024-07-18 13:11           ` Sabrina Dubroca
2024-07-18 13:27             ` Antonio Quartulli
2024-07-18 13:40               ` Sabrina Dubroca
2024-07-18 14:15                 ` Antonio Quartulli
2024-05-06  1:16 ` [PATCH net-next v3 11/24] ovpn: implement packet processing Antonio Quartulli
2024-05-12  8:46   ` Sabrina Dubroca
2024-05-13  7:14     ` Antonio Quartulli
2024-05-13  9:24       ` Sabrina Dubroca
2024-05-13  9:31         ` Antonio Quartulli
2024-05-22 14:08     ` Antonio Quartulli
2024-05-22 14:28       ` Andrew Lunn
2024-05-06  1:16 ` [PATCH net-next v3 12/24] ovpn: store tunnel and transport statistics Antonio Quartulli
2024-05-12  8:47   ` Sabrina Dubroca
2024-05-13  7:25     ` Antonio Quartulli
2024-05-13  9:19       ` Sabrina Dubroca
2024-05-13  9:33         ` Antonio Quartulli
2024-05-06  1:16 ` [PATCH net-next v3 13/24] ovpn: implement TCP transport Antonio Quartulli
2024-05-13 13:37   ` Antonio Quartulli
2024-05-13 15:34     ` Jakub Kicinski
2024-05-13 14:50   ` Sabrina Dubroca
2024-05-13 22:20     ` Antonio Quartulli
2024-05-14  8:58       ` Sabrina Dubroca
2024-05-14 22:11         ` Antonio Quartulli
2024-05-15 10:19           ` Sabrina Dubroca
2024-05-15 12:54             ` Antonio Quartulli
2024-05-15 14:55               ` Sabrina Dubroca
2024-05-15 19:44                 ` Antonio Quartulli
2024-05-15 20:35                   ` Sabrina Dubroca
2024-05-15 20:39                     ` Antonio Quartulli
2024-05-06  1:16 ` [PATCH net-next v3 14/24] ovpn: implement multi-peer support Antonio Quartulli
2024-05-28 14:44   ` Sabrina Dubroca
2024-05-28 19:41     ` Antonio Quartulli
2024-05-29 15:16       ` Sabrina Dubroca
2024-05-29 20:15         ` Antonio Quartulli
2024-05-29 20:45           ` Sabrina Dubroca
2024-05-06  1:16 ` [PATCH net-next v3 15/24] ovpn: implement peer lookup logic Antonio Quartulli
2024-05-28 16:42   ` Sabrina Dubroca
2024-05-28 20:09     ` Antonio Quartulli
2024-05-29 16:42       ` Sabrina Dubroca
2024-05-29 20:19         ` Antonio Quartulli
2024-05-06  1:16 ` [PATCH net-next v3 16/24] ovpn: implement keepalive mechanism Antonio Quartulli
2024-05-06  1:16 ` [PATCH net-next v3 17/24] ovpn: add support for updating local UDP endpoint Antonio Quartulli
2024-05-06  1:16 ` [PATCH net-next v3 18/24] ovpn: add support for peer floating Antonio Quartulli
2024-05-06  1:16 ` [PATCH net-next v3 19/24] ovpn: implement peer add/dump/delete via netlink Antonio Quartulli
2024-05-06  1:16 ` [PATCH net-next v3 20/24] ovpn: implement key add/del/swap " Antonio Quartulli
2024-05-06  1:16 ` [PATCH net-next v3 21/24] ovpn: kill key and notify userspace in case of IV exhaustion Antonio Quartulli
2024-05-06  1:16 ` [PATCH net-next v3 22/24] ovpn: notify userspace when a peer is deleted Antonio Quartulli
2024-05-06  1:16 ` [PATCH net-next v3 23/24] ovpn: add basic ethtool support Antonio Quartulli
2024-05-06  1:16 ` [PATCH net-next v3 24/24] testing/selftest: add test tool and scripts for ovpn module Antonio Quartulli
2024-05-07 23:55   ` Jakub Kicinski
2024-05-08  9:51     ` Antonio Quartulli
2024-05-09  0:50       ` Jakub Kicinski
2024-05-09  8:40         ` Antonio Quartulli
2024-05-07 23:48 ` [PATCH net-next v3 00/24] Introducing OpenVPN Data Channel Offload Jakub Kicinski
2024-05-08  9:56   ` Antonio Quartulli
2024-05-09  0:53     ` Jakub Kicinski
2024-05-09  8:41       ` Antonio Quartulli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Zjy-jPqyKo-6clve@hog \
    --to=sd@queasysnail.net \
    --cc=andrew@lunn.ch \
    --cc=antonio@openvpn.net \
    --cc=edumazet@google.com \
    --cc=esben@geanix.com \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=ryazanov.s.a@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).