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 15/24] ovpn: implement peer lookup logic
Date: Tue, 28 May 2024 18:42:16 +0200 [thread overview]
Message-ID: <ZlYJaIvXY3nuNd98@hog> (raw)
In-Reply-To: <20240506011637.27272-16-antonio@openvpn.net>
2024-05-06, 03:16:28 +0200, Antonio Quartulli wrote:
> +static struct in6_addr ovpn_nexthop_from_skb6(struct sk_buff *skb)
> +{
> + struct rt6_info *rt = (struct rt6_info *)skb_rtable(skb);
skb_rt6_info?
> +
> + if (!rt || !(rt->rt6i_flags & RTF_GATEWAY))
> + return ipv6_hdr(skb)->daddr;
> +
> + return rt->rt6i_gateway;
> +}
> +
> +/**
> + * ovpn_peer_get_by_vpn_addr4 - retrieve peer by its VPN IPv4 address
> + * @head: list head to search
> + * @addr: VPN IPv4 to use as search key
> + *
> + * Return: the peer if found or NULL otherwise
The doc for all those ovpn_peer_get_* functions could indicate that on
success, a reference on the peer is held.
[...]
> +static struct ovpn_peer *ovpn_peer_get_by_vpn_addr6(struct hlist_head *head,
> + struct in6_addr *addr)
> +{
> + struct ovpn_peer *tmp, *peer = NULL;
> + int i;
> +
> + rcu_read_lock();
> + hlist_for_each_entry_rcu(tmp, head, hash_entry_addr6) {
> + for (i = 0; i < 4; i++) {
> + if (addr->s6_addr32[i] !=
> + tmp->vpn_addrs.ipv6.s6_addr32[i])
> + continue;
> + }
ipv6_addr_equal
[...]
> + default:
> + return NULL;
> + }
> +
> + index = ovpn_peer_index(ovpn->peers.by_transp_addr, &ss, sa_len);
> + head = &ovpn->peers.by_transp_addr[index];
Maybe worth adding a get_bucket helper (with a better name :)) instead
of ovpn_peer_index, since all uses of ovpn_peer_index are followed by
a "head = TBL[index]" (or direct use in some hlist iterator), but the
index itself is not used later on, only the bucket.
> +
> + rcu_read_lock();
> + hlist_for_each_entry_rcu(tmp, head, hash_entry_transp_addr) {
> + found = ovpn_peer_transp_match(tmp, &ss);
> + if (!found)
nit: call ovpn_peer_transp_match directly and drop the found variable
> + continue;
> +
> + if (!ovpn_peer_hold(tmp))
> + continue;
> +
> + peer = tmp;
> + break;
> + }
> + rcu_read_unlock();
>
> return peer;
> }
> @@ -303,10 +427,28 @@ static struct ovpn_peer *ovpn_peer_get_by_id_p2p(struct ovpn_struct *ovpn,
>
> struct ovpn_peer *ovpn_peer_get_by_id(struct ovpn_struct *ovpn, u32 peer_id)
> {
> - struct ovpn_peer *peer = NULL;
> + struct ovpn_peer *tmp, *peer = NULL;
> + struct hlist_head *head;
> + u32 index;
>
> if (ovpn->mode == OVPN_MODE_P2P)
> - peer = ovpn_peer_get_by_id_p2p(ovpn, peer_id);
> + return ovpn_peer_get_by_id_p2p(ovpn, peer_id);
> +
> + index = ovpn_peer_index(ovpn->peers.by_id, &peer_id, sizeof(peer_id));
> + head = &ovpn->peers.by_id[index];
> +
> + rcu_read_lock();
> + hlist_for_each_entry_rcu(tmp, head, hash_entry_id) {
> + if (tmp->id != peer_id)
> + continue;
> +
> + if (!ovpn_peer_hold(tmp))
> + continue;
Can there ever be multiple peers with the same id? (ie, is it worth
continuing the loop if this fails? the same question probably applies
to ovpn_peer_get_by_transp_addr as well)
> + peer = tmp;
> + break;
> + }
> + rcu_read_unlock();
>
> return peer;
> }
> @@ -328,6 +470,11 @@ struct ovpn_peer *ovpn_peer_get_by_dst(struct ovpn_struct *ovpn,
> struct sk_buff *skb)
> {
> struct ovpn_peer *tmp, *peer = NULL;
> + struct hlist_head *head;
> + sa_family_t sa_fam;
> + struct in6_addr addr6;
> + __be32 addr4;
> + u32 index;
>
> /* in P2P mode, no matter the destination, packets are always sent to
> * the single peer listening on the other side
> @@ -338,15 +485,123 @@ struct ovpn_peer *ovpn_peer_get_by_dst(struct ovpn_struct *ovpn,
> if (likely(tmp && ovpn_peer_hold(tmp)))
> peer = tmp;
> rcu_read_unlock();
> + return peer;
> + }
> +
> + sa_fam = skb_protocol_to_family(skb);
> +
> + switch (sa_fam) {
> + case AF_INET:
> + addr4 = ovpn_nexthop_from_skb4(skb);
> + index = ovpn_peer_index(ovpn->peers.by_vpn_addr, &addr4,
> + sizeof(addr4));
> + head = &ovpn->peers.by_vpn_addr[index];
> +
> + peer = ovpn_peer_get_by_vpn_addr4(head, &addr4);
> + break;
> + case AF_INET6:
> + addr6 = ovpn_nexthop_from_skb6(skb);
> + index = ovpn_peer_index(ovpn->peers.by_vpn_addr, &addr6,
> + sizeof(addr6));
> + head = &ovpn->peers.by_vpn_addr[index];
> +
> + peer = ovpn_peer_get_by_vpn_addr6(head, &addr6);
The index -> head -> peer code is identical in get_by_dst and
get_by_src, it could be stuffed into ovpn_peer_get_by_vpn_addr{4,6}.
> + break;
> }
>
> return peer;
> }
[snip the _rt4 variant, comments apply to both]
> +/**
> + * ovpn_nexthop_from_rt6 - look up the IPv6 nexthop for the given destination
I'm a bit confused by this talk about "destination" when those two
functions are then used with the source address from the packet, from
a function called "get_by_src".
> + * @ovpn: the private data representing the current VPN session
> + * @dst: the destination to be looked up
> + *
> + * Looks up in the IPv6 system routing table the IO of the nexthop to be used
"the IO"?
> + * to reach the destination passed as argument. IF no nexthop can be found, the
> + * destination itself is returned as it probably has to be used as nexthop.
> + *
> + * Return: the IP of the next hop if found or the dst itself otherwise
"the dst" tends to refer to a dst_entry, maybe "or @dst otherwise"?
(though I'm not sure that's valid kdoc)
(also for ovpn_nexthop_from_rt4)
> + */
> +static struct in6_addr ovpn_nexthop_from_rt6(struct ovpn_struct *ovpn,
> + struct in6_addr dst)
> +{
> +#if IS_ENABLED(CONFIG_IPV6)
> + struct dst_entry *entry;
> + struct rt6_info *rt;
> + struct flowi6 fl = {
> + .daddr = dst,
> + };
> +
> + entry = ipv6_stub->ipv6_dst_lookup_flow(dev_net(ovpn->dev), NULL, &fl,
> + NULL);
> + if (IS_ERR(entry)) {
> + net_dbg_ratelimited("%s: no route to host %pI6c\n", __func__,
> + &dst);
> + /* if we end up here this packet is probably going to be
> + * thrown away later
> + */
> + return dst;
> + }
> +
> + rt = container_of(entry, struct rt6_info, dst);
dst_rt6_info(entry)
> +
> + if (!(rt->rt6i_flags & RTF_GATEWAY))
> + goto out;
> +
> + dst = rt->rt6i_gateway;
> +out:
> + dst_release((struct dst_entry *)rt);
> +#endif
> + return dst;
> +}
> +
> struct ovpn_peer *ovpn_peer_get_by_src(struct ovpn_struct *ovpn,
> struct sk_buff *skb)
> {
> struct ovpn_peer *tmp, *peer = NULL;
> + struct hlist_head *head;
> + sa_family_t sa_fam;
> + struct in6_addr addr6;
> + __be32 addr4;
> + u32 index;
>
> /* in P2P mode, no matter the destination, packets are always sent to
> * the single peer listening on the other side
> @@ -357,6 +612,28 @@ struct ovpn_peer *ovpn_peer_get_by_src(struct ovpn_struct *ovpn,
> if (likely(tmp && ovpn_peer_hold(tmp)))
> peer = tmp;
> rcu_read_unlock();
> + return peer;
> + }
> +
> + sa_fam = skb_protocol_to_family(skb);
> +
> + switch (sa_fam) {
nit:
switch (skb_protocol_to_family(skb))
seems a bit more readable to me (also in ovpn_peer_get_by_dst) - and
saves you from reverse xmas tree complaints (sa_fam should have been
after addr6)
> + case AF_INET:
> + addr4 = ovpn_nexthop_from_rt4(ovpn, ip_hdr(skb)->saddr);
> + index = ovpn_peer_index(ovpn->peers.by_vpn_addr, &addr4,
> + sizeof(addr4));
> + head = &ovpn->peers.by_vpn_addr[index];
> +
> + peer = ovpn_peer_get_by_vpn_addr4(head, &addr4);
> + break;
> + case AF_INET6:
> + addr6 = ovpn_nexthop_from_rt6(ovpn, ipv6_hdr(skb)->saddr);
> + index = ovpn_peer_index(ovpn->peers.by_vpn_addr, &addr6,
> + sizeof(addr6));
> + head = &ovpn->peers.by_vpn_addr[index];
> +
> + peer = ovpn_peer_get_by_vpn_addr6(head, &addr6);
> + break;
> }
>
> return peer;
> --
> 2.43.2
>
>
--
Sabrina
next prev parent reply other threads:[~2024-05-28 16:42 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
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 [this message]
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=ZlYJaIvXY3nuNd98@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 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.