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 12:09:00 +0200 [thread overview]
Message-ID: <ZjygvCgXFfrA4GRN@hog> (raw)
In-Reply-To: <b6a6c29b-ad78-4d6f-be1a-93615f27c956@openvpn.net>
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:
> > > diff --git a/drivers/net/ovpn/main.c b/drivers/net/ovpn/main.c
> > > index 33c0b004ce16..584cd7286aff 100644
> > > --- a/drivers/net/ovpn/main.c
> > > +++ b/drivers/net/ovpn/main.c
> > [...]
> > > +static void ovpn_struct_free(struct net_device *net)
> > > +{
> > > + struct ovpn_struct *ovpn = netdev_priv(net);
> > > +
> > > + rtnl_lock();
> >
> > ->priv_destructor can run from register_netdevice (already under
> > RTNL), this doesn't look right.
> >
> > > + list_del(&ovpn->dev_list);
> >
> > And if this gets called from register_netdevice, the list_add from
> > ovpn_iface_create hasn't run yet, so this will probably do strange
> > things?
>
> Argh, again I haven't considered a failure in register_netdevice and you are
> indeed right.
>
> Maybe it is better to call list_del() in the netdev notifier, upon
> NETDEV_UNREGISTER event?
I'd like to avoid splitting the clean up code over so maybe different
functions and called through different means. Keep it simple.
AFAICT the only reason you need this list is to delete your devices on
netns exit, so if we can get rid of that the list can go away.
> > > +static int ovpn_net_open(struct net_device *dev)
> > > +{
> > > + struct in_device *dev_v4 = __in_dev_get_rtnl(dev);
> > > +
> > > + if (dev_v4) {
> > > + /* disable redirects as Linux gets confused by ovpn handling
> > > + * same-LAN routing
> > > + */
> > > + IN_DEV_CONF_SET(dev_v4, SEND_REDIRECTS, false);
> > > + IPV4_DEVCONF_ALL(dev_net(dev), SEND_REDIRECTS) = false;
> >
> > Jakub, are you ok with that? This feels a bit weird to have in the
> > middle of a driver.
>
> Let me share what the problem is (copied from the email I sent to Andrew
> Lunn as he was also curious about this):
>
> The reason for requiring this setting lies in the OpenVPN server acting as
> relay point (star topology) for hosts in the same subnet.
>
> Example: given the a.b.c.0/24 IP network, you have .2 that in order to talk
> to .3 must have its traffic relayed by .1 (the server).
>
> When the kernel (at .1) sees this traffic it will send the ICMP redirects,
> because it believes that .2 should directly talk to .3 without passing
> through .1.
So only the server would need to stop sending them, not the client?
(or the client would need to ignore them)
But the kernel has no way of knowing if an ovpn device is on a client
or a server?
> Of course it makes sense in a normal network with a classic broadcast
> domain, but this is not the case in a VPN implemented as a star topology.
>
> Does it make sense?
It looks like the problem is that ovpn links are point-to-point
(instead of a broadcast LAN kind of link where redirects would make
sense), and the kernel doesn't handle it that way.
> The only way I see to fix this globally is to have an extra flag in the
> netdevice signaling this peculiarity and thus disabling ICMP redirects
> automatically.
>
> Note: wireguard has those lines too, as it probably needs to address the
> same scenario.
I've noticed a lot of similarities in some bits I've looked at, and I
hate that this is turning into another pile of duplicate code like
vxlan/geneve, bond/team, etc :(
> > [...]
> > > +void ovpn_iface_destruct(struct ovpn_struct *ovpn)
> > > +{
> > > + ASSERT_RTNL();
> > > +
> > > + netif_carrier_off(ovpn->dev);
> > > +
> > > + ovpn->registered = false;
> > > +
> > > + unregister_netdevice(ovpn->dev);
> > > + synchronize_net();
> >
> > If this gets called from the loop in ovpn_netns_pre_exit, one
> > synchronize_net per ovpn device would seem quite expensive.
>
> As per your other comment, maybe I should just remove the synchronize_net()
> entirely since it'll be the core to take care of inflight packets?
There's a synchronize_net in unregister_netdevice_many_notify, so I'd
say you can get rid of it here.
> > > 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, 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.
> > > @@ -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)
> > > +{
> > > + 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. 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), 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?
--
Sabrina
next prev parent reply other threads:[~2024-05-09 10:09 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 [this message]
2024-05-09 10:35 ` Antonio Quartulli
2024-05-09 12:16 ` Sabrina Dubroca
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=ZjygvCgXFfrA4GRN@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