From patchwork Wed Jul 23 15:32:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gert Doering X-Patchwork-Id: 4325 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:3644:b0:671:5a2c:6455 with SMTP id a4csp248467mai; Wed, 23 Jul 2025 08:32:44 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVfnmTinTgdgKsd2FVJ/z1B4Ue7vHJcSVua0AHfPuwTKzqyqN9qQSNCSmaV5MSBSLlryVWhZ8Q1VLI=@openvpn.net X-Google-Smtp-Source: AGHT+IHloP4nJSuO/kZVrmroEht4FWLCR+7B6ciq7uR9pu41KpJ7Omr3NCtKUzoOYKjUGP64W3Bp X-Received: by 2002:a05:6830:650e:b0:72b:9d8d:5881 with SMTP id 46e09a7af769-74088cf49d7mr2507430a34.28.1753284763764; Wed, 23 Jul 2025 08:32:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1753284763; cv=none; d=google.com; s=arc-20240605; b=RnsUGNFzb8+oOMOPuDAkAzYpkYOYm9uMB3spv4hzmxoAlUYwmv1M373+PXmPwnsU+d LwNpqp6+1/XWX6/4mtM4HAP3Opz9SIoJZBUFWkSLu3S8XMEOU6LNmAN8fJ0dP7ALC0rz lACd9wajYD/+kH2eJ5IzqSYit/RvL9lbjNo6B+fCbLnkgL9XvZSuopUdTsBnillwbU0S LnCkFp/VC7Bm6EfayUzcYkd4LkIBgo25tE/X/uGFkZAjEToxXDHx0aLn/OQng3gjtFCl mnv5Yl9rNArVDdAslfpbgi0mgNaoUd9Wo3oibYG6No6wwEf2eZCB+aze1p6vWmiJzXZV XPcg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:dkim-signature:dkim-signature; bh=UZyMkfvDdawVK+uU3p6eXuBQB2Wi/ibYMjElwzSzpEU=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=AkOVONc1M6FACmkFz9wObTyRscpr7oaWrUmBbohIU6BtLqW1i7O5swXhYm9rRPlHkM TOVaW3btHuvx3OsY5G/oSYqczWTXJ4SC68PkYWoUDFerGG1MaOnk2EKZYfRxcrHTkkZV nk1eHOWdGC8beTHntpHO6V3OWa7Xjon2JRDiHamWcuTvlJqxUsKSzXmTCcNH2gjOkXjr Mj4NLq6ygd3DA+9rNat66vt/YQxzK+VvHf7Sp428HAM7tPPWfWdyKDqCrqfr2CjKCOrc nFuQu5rvZMCNseTN5bx6YIBqcLcVNyuAxgWdqdDjG2dlJuN8vgJqcTozEFeI5aDsP4nW GWVw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=GvTuSTdk; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=MdAc9Fpe; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=gBkg6GmU; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 46e09a7af769-73e83b401f3si6192106a34.247.2025.07.23.08.32.43 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 23 Jul 2025 08:32:43 -0700 (PDT) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=GvTuSTdk; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=MdAc9Fpe; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=gBkg6GmU; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Subject:MIME-Version:References:In-Reply-To:Message-ID:Date:To:From:Sender: Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=UZyMkfvDdawVK+uU3p6eXuBQB2Wi/ibYMjElwzSzpEU=; b=GvTuSTdkC2StPyGQLzR2HcmK2s vpHt3dmo5XlLgybO97P4aVsLDNULUILv6aBz56gZZMweTlKqOM1WDmCHJyH4Osv1RQ7qY/ag97p2Z ++oQ01teUvDStzna7BJgZ/ln15cagiqLXyszYfFR20IlbZso45EUSg60fVV9kE0I+5t8=; Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1uebSR-0002RE-VO; Wed, 23 Jul 2025 15:32:40 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1uebSQ-0002Qs-0L for openvpn-devel@lists.sourceforge.net; Wed, 23 Jul 2025 15:32:38 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=OqNsURT3jnAPvi2tSkVrN5prMBuxcmyqHZqvH50kf/E=; b=MdAc9FpeXsaYLh9Deq9MfGwlVz zmLzb9YF/cEGiyuJNWK1u0CQMYjhFlYT9nEDK9glgDlySs1w/+GxZqJM2FFNDNn7OqsDR9aPN6AXW VWzHaSqWi1GokLM6FORbQMvZXExtNAqe2GiyqERUt6jgy+icx6qHcd8sQ+6vGzGO6S9Q=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=OqNsURT3jnAPvi2tSkVrN5prMBuxcmyqHZqvH50kf/E=; b=gBkg6GmUamt9yjbql0pANfUpU9 moQncawN1IZ4r6E+CCTS/smeBemOAD14zixiXOGoLdCdncco932nhOWclC1rq7JVGX1m4zB+1XP1n xjcBHjTmLCq07UmGASbxEafdedgqX4zXWzi+g171cJTONGFAc0yXH79PkibSrlhrrxsA=; Received: from [193.149.48.143] (helo=blue.greenie.muc.de) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1uebSP-00046s-6s for openvpn-devel@lists.sourceforge.net; Wed, 23 Jul 2025 15:32:38 +0000 Received: from blue.greenie.muc.de (localhost [127.0.0.1]) by blue.greenie.muc.de (8.17.1.9/8.17.1.9) with ESMTP id 56NFWPmD013738 for ; Wed, 23 Jul 2025 17:32:25 +0200 Received: (from gert@localhost) by blue.greenie.muc.de (8.17.1.9/8.17.1.9/Submit) id 56NFWPnA013737 for openvpn-devel@lists.sourceforge.net; Wed, 23 Jul 2025 17:32:25 +0200 From: Gert Doering To: openvpn-devel@lists.sourceforge.net Date: Wed, 23 Jul 2025 17:32:19 +0200 Message-ID: <20250723153224.13708-1-gert@greenie.muc.de> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Score: 1.3 (+) X-Spam-Report: Spam detection software, running on the system "sfi-spamd-1.hosts.colo.sdot.me", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: From: Antonio Quartulli ovpn_handle_msg() is soon becoming the main entry point for parsing *all* incoming netlink messages. For this reason it is essential that this function is kept simple and slim. Content analysis details: (1.3 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 1.3 RDNS_NONE Delivered to internal network by a host with no rDNS X-Headers-End: 1uebSP-00046s-6s Subject: [Openvpn-devel] [PATCH v4] dco_linux: factor out netlink notification code X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1838452324374316136?= X-GMAIL-MSGID: =?utf-8?q?1838452324374316136?= From: Antonio Quartulli ovpn_handle_msg() is soon becoming the main entry point for parsing *all* incoming netlink messages. For this reason it is essential that this function is kept simple and slim. Move all code parsing netlink multicast notifications to their own helpers and then invoke them. This patch does not introduce any functional change. It is intended in preparation for extending ovpn_handle_msg() to become a genering netlink message parser. Change-Id: I7bbc40b7b66f6e0512cd2cf9791766bcc4970461 Signed-off-by: Antonio Quartulli Acked-by: Gert Doering --- This change was reviewed on Gerrit and approved by at least one developer. I request to merge it to master. Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1099 This mail reflects revision 4 of this Change. Acked-by according to Gerrit (reflected above): Gert Doering diff --git a/src/openvpn/dco_linux.c b/src/openvpn/dco_linux.c index ec6efaa..7c639d9 100644 --- a/src/openvpn/dco_linux.c +++ b/src/openvpn/dco_linux.c @@ -956,6 +956,164 @@ return NL_OK; } +static bool +ovpn_iface_check(dco_context_t *dco, struct nlattr *attrs[]) +{ + /* we must know which interface this message is referring to in order to + * avoid mixing messages for other instances + */ + if (!attrs[OVPN_A_IFINDEX]) + { + msg(D_DCO, "ovpn-dco: Received message without ifindex"); + return false; + } + + uint32_t ifindex = nla_get_u32(attrs[OVPN_A_IFINDEX]); + if (ifindex != dco->ifindex) + { + msg(D_DCO_DEBUG, + "ovpn-dco: ignoring message for foreign ifindex %d", ifindex); + return false; + } + + return true; +} + +static int +ovpn_handle_peer_del_ntf(dco_context_t *dco, struct nlattr *attrs[]) +{ + if (!ovpn_iface_check(dco, attrs)) + { + return NL_STOP; + } + + if (!attrs[OVPN_A_PEER]) + { + msg(D_DCO, "ovpn-dco: no peer in PEER_DEL_NTF message"); + return NL_STOP; + } + + struct nlattr *dp_attrs[OVPN_A_PEER_MAX + 1]; + if (nla_parse_nested(dp_attrs, OVPN_A_PEER_MAX, attrs[OVPN_A_PEER], + NULL)) + { + msg(D_DCO, "ovpn-dco: can't parse peer in PEER_DEL_NTF messsage"); + return NL_STOP; + } + + if (!dp_attrs[OVPN_A_PEER_DEL_REASON]) + { + msg(D_DCO, "ovpn-dco: no reason in PEER_DEL_NTF message"); + return NL_STOP; + } + if (!dp_attrs[OVPN_A_PEER_ID]) + { + msg(D_DCO, "ovpn-dco: no peer-id in PEER_DEL_NTF message"); + return NL_STOP; + } + + int reason = nla_get_u32(dp_attrs[OVPN_A_PEER_DEL_REASON]); + unsigned int peerid = nla_get_u32(dp_attrs[OVPN_A_PEER_ID]); + + msg(D_DCO_DEBUG, "ovpn-dco: received CMD_PEER_DEL_NTF, ifindex: %d, peer-id %u, reason: %d", + dco->ifindex, peerid, reason); + dco->dco_message_peer_id = peerid; + dco->dco_del_peer_reason = reason; + dco->dco_message_type = OVPN_CMD_PEER_DEL_NTF; + + return NL_OK; +} + +static int +ovpn_handle_peer_float_ntf(dco_context_t *dco, struct nlattr *attrs[]) +{ + if (!ovpn_iface_check(dco, attrs)) + { + return NL_STOP; + } + + if (!attrs[OVPN_A_PEER]) + { + msg(D_DCO, "ovpn-dco: no peer in PEER_FLOAT_NTF message"); + return NL_STOP; + } + + struct nlattr *fp_attrs[OVPN_A_PEER_MAX + 1]; + if (nla_parse_nested(fp_attrs, OVPN_A_PEER_MAX, attrs[OVPN_A_PEER], + NULL)) + { + msg(D_DCO, "ovpn-dco: can't parse peer in PEER_FLOAT_NTF messsage"); + return NL_STOP; + } + + if (!fp_attrs[OVPN_A_PEER_ID]) + { + msg(D_DCO, "ovpn-dco: no peer-id in PEER_FLOAT_NTF message"); + return NL_STOP; + } + uint32_t peerid = nla_get_u32(fp_attrs[OVPN_A_PEER_ID]); + + if (!ovpn_parse_float_addr(fp_attrs, (struct sockaddr *)&dco->dco_float_peer_ss)) + { + return NL_STOP; + } + + struct gc_arena gc = gc_new(); + msg(D_DCO_DEBUG, + "ovpn-dco: received CMD_PEER_FLOAT_NTF, ifindex: %u, peer-id %u, address: %s", + dco->ifindex, peerid, print_sockaddr((struct sockaddr *)&dco->dco_float_peer_ss, &gc)); + dco->dco_message_peer_id = (int)peerid; + dco->dco_message_type = OVPN_CMD_PEER_FLOAT_NTF; + + gc_free(&gc); + + return NL_OK; +} + +static int +ovpn_handle_key_swap_ntf(dco_context_t *dco, struct nlattr *attrs[]) +{ + if (!ovpn_iface_check(dco, attrs)) + { + return NL_STOP; + } + + if (!attrs[OVPN_A_KEYCONF]) + { + msg(D_DCO, "ovpn-dco: no keyconf in KEY_SWAP_NTF message"); + return NL_STOP; + } + + struct nlattr *dp_attrs[OVPN_A_KEYCONF_MAX + 1]; + if (nla_parse_nested(dp_attrs, OVPN_A_KEYCONF_MAX, + attrs[OVPN_A_KEYCONF], NULL)) + { + msg(D_DCO, "ovpn-dco: can't parse keyconf in KEY_SWAP_NTF message"); + return NL_STOP; + } + if (!dp_attrs[OVPN_A_KEYCONF_PEER_ID]) + { + msg(D_DCO, "ovpn-dco: no peer-id in KEY_SWAP_NTF message"); + return NL_STOP; + } + if (!dp_attrs[OVPN_A_KEYCONF_KEY_ID]) + { + msg(D_DCO, "ovpn-dco: no key-id in KEY_SWAP_NTF message"); + return NL_STOP; + } + + int key_id = nla_get_u16(dp_attrs[OVPN_A_KEYCONF_KEY_ID]); + unsigned int peer_id = nla_get_u32(dp_attrs[OVPN_A_KEYCONF_PEER_ID]); + + msg(D_DCO_DEBUG, "ovpn-dco: received CMD_KEY_SWAP_NTF, ifindex: %d, peer-id %u, key-id: %d", + dco->ifindex, peer_id, key_id); + dco->dco_message_peer_id = peer_id; + dco->dco_message_key_id = key_id; + dco->dco_message_type = OVPN_CMD_KEY_SWAP_NTF; + + return NL_OK; +} + /* This function parses any netlink message sent by ovpn-dco to userspace */ static int ovpn_handle_msg(struct nl_msg *msg, void *arg) @@ -979,24 +1137,6 @@ return NL_STOP; } - /* we must know which interface this message is referring to in order to - * avoid mixing messages for other instances - */ - if (!attrs[OVPN_A_IFINDEX]) - { - msg(D_DCO, "ovpn-dco: Received message without ifindex"); - return NL_STOP; - } - - uint32_t ifindex = nla_get_u32(attrs[OVPN_A_IFINDEX]); - if (ifindex != dco->ifindex) - { - msg(D_DCO_DEBUG, - "ovpn-dco: ignoring message (type=%d) for foreign ifindex %d", - gnlh->cmd, ifindex); - return NL_STOP; - } - /* based on the message type, we parse the subobject contained in the * message, that stores the type-specific attributes. * @@ -1008,116 +1148,17 @@ { case OVPN_CMD_PEER_DEL_NTF: { - if (!attrs[OVPN_A_PEER]) - { - msg(D_DCO, "ovpn-dco: no peer in PEER_DEL_NTF message"); - return NL_STOP; - } - - struct nlattr *dp_attrs[OVPN_A_PEER_MAX + 1]; - if (nla_parse_nested(dp_attrs, OVPN_A_PEER_MAX, attrs[OVPN_A_PEER], - NULL)) - { - msg(D_DCO, "ovpn-dco: can't parse peer in PEER_DEL_NTF messsage"); - return NL_STOP; - } - - if (!dp_attrs[OVPN_A_PEER_DEL_REASON]) - { - msg(D_DCO, "ovpn-dco: no reason in PEER_DEL_NTF message"); - return NL_STOP; - } - if (!dp_attrs[OVPN_A_PEER_ID]) - { - msg(D_DCO, "ovpn-dco: no peer-id in PEER_DEL_NTF message"); - return NL_STOP; - } - - int reason = nla_get_u32(dp_attrs[OVPN_A_PEER_DEL_REASON]); - unsigned int peerid = nla_get_u32(dp_attrs[OVPN_A_PEER_ID]); - - msg(D_DCO_DEBUG, "ovpn-dco: received CMD_PEER_DEL_NTF, ifindex: %d, peer-id %u, reason: %d", - ifindex, peerid, reason); - dco->dco_message_peer_id = peerid; - dco->dco_del_peer_reason = reason; - dco->dco_message_type = OVPN_CMD_PEER_DEL_NTF; - break; + return ovpn_handle_peer_del_ntf(dco, attrs); } case OVPN_CMD_PEER_FLOAT_NTF: { - if (!attrs[OVPN_A_PEER]) - { - msg(D_DCO, "ovpn-dco: no peer in PEER_FLOAT_NTF message"); - return NL_STOP; - } - - struct nlattr *fp_attrs[OVPN_A_PEER_MAX + 1]; - if (nla_parse_nested(fp_attrs, OVPN_A_PEER_MAX, attrs[OVPN_A_PEER], - NULL)) - { - msg(D_DCO, "ovpn-dco: can't parse peer in PEER_FLOAT_NTF messsage"); - return NL_STOP; - } - - if (!fp_attrs[OVPN_A_PEER_ID]) - { - msg(D_DCO, "ovpn-dco: no peer-id in PEER_FLOAT_NTF message"); - return NL_STOP; - } - uint32_t peerid = nla_get_u32(fp_attrs[OVPN_A_PEER_ID]); - - if (!ovpn_parse_float_addr(fp_attrs, (struct sockaddr *)&dco->dco_float_peer_ss)) - { - return NL_STOP; - } - - struct gc_arena gc = gc_new(); - msg(D_DCO_DEBUG, - "ovpn-dco: received CMD_PEER_FLOAT_NTF, ifindex: %u, peer-id %u, address: %s", - ifindex, peerid, print_sockaddr((struct sockaddr *)&dco->dco_float_peer_ss, &gc)); - dco->dco_message_peer_id = (int)peerid; - dco->dco_message_type = OVPN_CMD_PEER_FLOAT_NTF; - - gc_free(&gc); - break; + return ovpn_handle_peer_float_ntf(dco, attrs); } case OVPN_CMD_KEY_SWAP_NTF: { - if (!attrs[OVPN_A_KEYCONF]) - { - msg(D_DCO, "ovpn-dco: no keyconf in KEY_SWAP_NTF message"); - return NL_STOP; - } - - struct nlattr *dp_attrs[OVPN_A_KEYCONF_MAX + 1]; - if (nla_parse_nested(dp_attrs, OVPN_A_KEYCONF_MAX, - attrs[OVPN_A_KEYCONF], NULL)) - { - msg(D_DCO, "ovpn-dco: can't parse keyconf in KEY_SWAP_NTF message"); - return NL_STOP; - } - if (!dp_attrs[OVPN_A_KEYCONF_PEER_ID]) - { - msg(D_DCO, "ovpn-dco: no peer-id in KEY_SWAP_NTF message"); - return NL_STOP; - } - if (!dp_attrs[OVPN_A_KEYCONF_KEY_ID]) - { - msg(D_DCO, "ovpn-dco: no key-id in KEY_SWAP_NTF message"); - return NL_STOP; - } - - int key_id = nla_get_u16(dp_attrs[OVPN_A_KEYCONF_KEY_ID]); - unsigned int peer_id = nla_get_u32(dp_attrs[OVPN_A_KEYCONF_PEER_ID]); - - msg(D_DCO_DEBUG, "ovpn-dco: received CMD_KEY_SWAP_NTF, ifindex: %d, peer-id %u, key-id: %d", - ifindex, peer_id, key_id); - dco->dco_message_peer_id = peer_id; - dco->dco_message_key_id = key_id; - dco->dco_message_type = OVPN_CMD_KEY_SWAP_NTF; - break; + return ovpn_handle_key_swap_ntf(dco, attrs); } default: