Re: [PATCH net-next v2 14/22] ovpn: implement peer lookup logic
From: Antonio Quartulli <antonio@openvpn.net>
Date: 2024-03-06 15:33:13
On 05/03/2024 16:16, Simon Horman wrote:
On Mon, Mar 04, 2024 at 04:09:05PM +0100, Antonio Quartulli wrote:quoted
In a multi-peer scenario there are a number of situations when a specific peer needs to be looked up. We may want to lookup a peer by: 1. its ID 2. its VPN destination IP 3. its tranport IP/port couplenit: transport checkpatch.pl --codespell is your friend here.
Thanks for this hint too!
quoted
For each of the above, there is a specific routing table referencing all peers for fast look up. Case 2. is a bit special in the sense that an outgoing packet may not be sent to the peer VPN IP directly, but rather to a network behind it. For this reason we first perform a nexthop lookup in the system routing table and then we use the retrieved nexthop as peer search key. Signed-off-by: Antonio Quartulli <antonio@openvpn.net>...quoted
+/** + * ovpn_nexthop_lookup4() - looks up the IP of the nexthop for the given destination + * + * Looks up in the IPv4 system routing table the IP of the nexthop to be used + * 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. + * + * @ovpn: the private data representing the current VPN session + * @dst: the destination to be looked upI think you need to document @src instead of @dst here.
Right
quoted
+ * + * Return the IP of the next hop if found or the dst itself otherwise + */ +static __be32 ovpn_nexthop_lookup4(struct ovpn_struct *ovpn, __be32 src) +{ + struct rtable *rt; + struct flowi4 fl = { + .daddr = src + }; + + rt = ip_route_output_flow(dev_net(ovpn->dev), &fl, NULL); + if (IS_ERR(rt)) { + net_dbg_ratelimited("%s: no nexthop found for %pI4\n", ovpn->dev->name, &src); + /* if we end up here this packet is probably going to be + * thrown away later + */ + return src; + } + + if (!rt->rt_uses_gateway) + goto out; + + src = rt->rt_gw4; +out: + return src; +} + +/** + * ovpn_nexthop_lookup6() - looks up the IPv6 of the nexthop for the given destination + * + * Looks up in the IPv6 system routing table the IP of the nexthop to be used + * 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. + * + * @ovpn: the private data representing the current VPN session + * @dst: the destination to be looked upAnd here.
Right.
quoted
+ * + * Return the IP of the next hop if found or the dst itself otherwise + */ +static struct in6_addr ovpn_nexthop_lookup6(struct ovpn_struct *ovpn, struct in6_addr addr) +{ +#if IS_ENABLED(CONFIG_IPV6) + struct rt6_info *rt; + struct flowi6 fl = { + .daddr = addr, + }; + + rt = (struct rt6_info *)ipv6_stub->ipv6_dst_lookup_flow(dev_net(ovpn->dev), NULL, &fl, + NULL); + if (IS_ERR(rt)) { + net_dbg_ratelimited("%s: no nexthop found for %pI6\n", ovpn->dev->name, &addr); + /* if we end up here this packet is probably going to be thrown away later */ + return addr; + } + + if (rt->rt6i_flags & RTF_GATEWAY) + addr = rt->rt6i_gateway; + + dst_release((struct dst_entry *)rt); +#endif + return addr; +}...
Thanks a lot. Regards, -- Antonio Quartulli OpenVPN Inc.