ovpn_sock = ovpn_socket_from_udp_sock(sk); if (unlikely(!ovpn_sock)) {
net_err_ratelimited("ovpn: %s invoked on non ovpn socket\n",
__func__); goto drop_noovpn;
}
ovpn = ovpn_sock->ovpn; if (unlikely(!ovpn)) {
net_err_ratelimited("ovpn: cannot obtain ovpn object from UDP socket\n"); goto drop_noovpn;
}
/* Make sure the first 4 bytes of the skb data buffer after the UDP *headerareaccessible. *TheyarerequiredtofetchtheOPcode,thekeyIDandthepeerID.
*/ if (unlikely(!pskb_may_pull(skb, sizeof(struct udphdr) +
OVPN_OPCODE_SIZE))) {
net_dbg_ratelimited("%s: packet too small from UDP socket\n",
netdev_name(ovpn->dev)); goto drop;
}
opcode = ovpn_opcode_from_skb(skb, sizeof(struct udphdr)); if (unlikely(opcode != OVPN_DATA_V2)) { /* DATA_V1 is not supported */ if (opcode == OVPN_DATA_V1) goto drop;
/* unknown or control packet: let it bubble up to userspace */ return1;
}
peer_id = ovpn_peer_id_from_skb(skb, sizeof(struct udphdr)); /* some OpenVPN server implementations send data packets with the *peer-idsettoUNDEF.Inthiscaseweskipthepeerlookupbypeer-id *andwetrywiththetransportaddress
*/ if (peer_id == OVPN_PEER_ID_UNDEF)
peer = ovpn_peer_get_by_transp_addr(ovpn, skb); else
peer = ovpn_peer_get_by_id(ovpn, peer_id);
if (unlikely(!peer)) goto drop;
/* pop off outer UDP header */
__skb_pull(skb, sizeof(struct udphdr));
ovpn_recv(peer, skb); return0;
local_bh_disable();
rt = dst_cache_get_ip4(cache, &fl.saddr); if (rt) goto transmit;
if (unlikely(!inet_confirm_addr(sock_net(sk), NULL, 0, fl.saddr,
RT_SCOPE_HOST))) { /* we may end up here when the cached address is not usable *anymore.Inthiscaseweresetaddress/cacheandperforma *newlookup
*/
fl.saddr = 0;
spin_lock_bh(&peer->lock);
bind->local.ipv4.s_addr = 0;
spin_unlock_bh(&peer->lock);
dst_cache_reset(cache);
}
local_bh_disable();
dst = dst_cache_get_ip6(cache, &fl.saddr); if (dst) goto transmit;
if (unlikely(!ipv6_chk_addr(sock_net(sk), &fl.saddr, NULL, 0))) { /* we may end up here when the cached address is not usable *anymore.Inthiscaseweresetaddress/cacheandperforma *newlookup
*/
fl.saddr = in6addr_any;
spin_lock_bh(&peer->lock);
bind->local.ipv6 = in6addr_any;
spin_unlock_bh(&peer->lock);
dst_cache_reset(cache);
}
dst = ipv6_stub->ipv6_dst_lookup_flow(sock_net(sk), sk, &fl, NULL); if (IS_ERR(dst)) {
ret = PTR_ERR(dst);
net_dbg_ratelimited("%s: no route to host %pISpc: %d\n",
netdev_name(peer->ovpn->dev),
&bind->remote.in6, ret); goto err;
}
dst_cache_set_ip6(cache, dst, &fl.saddr);
transmit: /* user IPv6 packets may be larger than the transport interface *MTU(afterencapsulation),however,sincetheyarelocally *generatedweshouldensuretheygetfragmented. *Settingtheignore_dfflagto1willinstructip6_fragment()to *fragmentpacketsifneeded. * *NOTE:thisisnotneededforIPv4becausewepassdf=0to *udp_tunnel_xmit_skb()
*/
skb->ignore_df = 1;
udp_tunnel6_xmit_skb(dst, sk, skb, skb->dev, &fl.saddr, &fl.daddr, 0,
ip6_dst_hoplimit(dst), 0, fl.fl6_sport,
fl.fl6_dport, udp_get_no_check6_tx(sk), 0);
ret = 0;
err:
local_bh_enable(); return ret;
} #endif
/* make sure no pre-existing encapsulation handler exists */
rcu_read_lock();
old_data = rcu_dereference_sk_user_data(ovpn_sock->sk); if (!old_data) { /* socket is currently unused - we can take it */
rcu_read_unlock();
setup_udp_tunnel_sock(sock_net(ovpn_sock->sk), sock, &cfg); return0;
}
/* socket is in use. We need to understand if it's owned by this ovpn *instanceorbysomethingelse. *Intheformercase,wecanincreasetherefcounterandhappily *useit,becausethesameUDPsocketisexpectedtobesharedamong *differentpeers. * *UnlikelyTCP,asingleUDPsocketcanbeusedtotalktomanyremote *hostsandthereforeopenvpninstantiatesoneonlyforallitspeers
*/ if ((READ_ONCE(udp_sk(ovpn_sock->sk)->encap_type) == UDP_ENCAP_OVPNINUDP) &&
old_data->ovpn == ovpn) {
netdev_dbg(ovpn->dev, "provided socket already owned by this interface\n");
ret = -EALREADY;
} else {
netdev_dbg(ovpn->dev, "provided socket already taken by other user\n");
ret = -EBUSY;
}
rcu_read_unlock();
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.12Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-09-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.