From patchwork Wed Oct 2 19:19:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 1992138 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=nwl.cc header.i=@nwl.cc header.a=rsa-sha256 header.s=mail2022 header.b=goHH625I; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2604:1380:45d1:ec00::1; helo=ny.mirrors.kernel.org; envelope-from=netfilter-devel+bounces-4194-incoming=patchwork.ozlabs.org@vger.kernel.org; receiver=patchwork.ozlabs.org) Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org [IPv6:2604:1380:45d1:ec00::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4XJl4h0p4Lz1xtY for ; Thu, 3 Oct 2024 05:20:03 +1000 (AEST) Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 13ED41C22C6A for ; Wed, 2 Oct 2024 19:20:02 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0359D215F63; Wed, 2 Oct 2024 19:19:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=nwl.cc header.i=@nwl.cc header.b="goHH625I" X-Original-To: netfilter-devel@vger.kernel.org Received: from orbyte.nwl.cc (orbyte.nwl.cc [151.80.46.58]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2D88C12CD88 for ; Wed, 2 Oct 2024 19:19:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=151.80.46.58 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727896797; cv=none; b=mvUs42aisZ6cOJTS/st5XQlgL5glyCmgrrZSlp+b8cX36a3PhC9C3MFsoo2tgO3KfrXHXc1R4clPwlJHqloAEKBMCZLm101/SvndKr/quapAi+lLeED50ydrTLGyjpcjk/FBGstn+HpCVC3IHuPzu9bavpB1oDsxwbL1JpV0bpk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727896797; c=relaxed/simple; bh=kZP5CKAWBAGYVBdW2aEOzX1flzTaeYWhH/eN7r+lu7c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TfG4xKbxhiLukXLMda+0WC4RgBEjDif2Aj33ORaGkOIv8W3ttaq5fpe9FrAplVMjARQhUi+3nP+b+wailcauV/N9k2uJIFG4a51TaXyCNQR6NgcUz1eqwC5ayuJ0EQf0BAslCNG+TL86ckvB4dCqhqkrtXlolvPcq5tktG3YKiw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nwl.cc; spf=pass smtp.mailfrom=nwl.cc; dkim=pass (2048-bit key) header.d=nwl.cc header.i=@nwl.cc header.b=goHH625I; arc=none smtp.client-ip=151.80.46.58 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nwl.cc Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nwl.cc DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nwl.cc; s=mail2022; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To: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=cWpxR1TSIQlQKJoBU8vKgP6/4Qt4DfPbB3p3yGOMHtQ=; b=goHH625I7cXt5GspEsMJAdo3bl GkIBmoaA1Y57NPZt9Re/ytNpEz++ZstN5MQ6Qm0+I9oC2lzkgMlUFG1PjqUTadbLNuVvPs4mHOBQZ y3CGULDTRmYVOHw54IMSfyNhMyG2AG5oUYAs7WkK16F59WLDWeFAfep8RyMKIn8avV5AA324tolKq 7VcFMkCIZruQ5A2pnFZUJMa2zuTgCrau1h2oEdeaQzbr08r2Z3iYYduSr3dI7ErAg9OLlVXrVMyWY t3Dzy5r2YgST4g9Sd1yD01JB2Xs7a4Ubc22fBL7Guyftm+z/Rx33nXYz+PJX0wHrw0Pvf17/sG98X 6mquUNfg==; Received: from localhost ([::1] helo=xic) by orbyte.nwl.cc with esmtp (Exim 4.97.1) (envelope-from ) id 1sw4t0-000000002lK-2Hs8; Wed, 02 Oct 2024 21:19:46 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [libnftnl PATCH 1/4] include: utils.h needs errno.h Date: Wed, 2 Oct 2024 21:19:38 +0200 Message-ID: <20241002191941.8410-2-phil@nwl.cc> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241002191941.8410-1-phil@nwl.cc> References: <20241002191941.8410-1-phil@nwl.cc> Precedence: bulk X-Mailing-List: netfilter-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Otherwise includers may face 'errno' undeclared errors. Fixes: 26c945057d742 ("src: split internal.h is smaller files") Signed-off-by: Phil Sutter --- include/utils.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/utils.h b/include/utils.h index eed61277595e2..247d99d19dd7f 100644 --- a/include/utils.h +++ b/include/utils.h @@ -1,6 +1,7 @@ #ifndef LIBNFTNL_UTILS_H #define LIBNFTNL_UTILS_H 1 +#include #include #include #include From patchwork Wed Oct 2 19:19:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 1992139 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=nwl.cc header.i=@nwl.cc header.a=rsa-sha256 header.s=mail2022 header.b=NxhfB7kX; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=147.75.48.161; helo=sy.mirrors.kernel.org; envelope-from=netfilter-devel+bounces-4195-incoming=patchwork.ozlabs.org@vger.kernel.org; receiver=patchwork.ozlabs.org) Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org [147.75.48.161]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4XJl4h3jmgz1xtn for ; Thu, 3 Oct 2024 05:20:04 +1000 (AEST) Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id D2336B21A31 for ; Wed, 2 Oct 2024 19:20:03 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 3616812CD88; Wed, 2 Oct 2024 19:19:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=nwl.cc header.i=@nwl.cc header.b="NxhfB7kX" X-Original-To: netfilter-devel@vger.kernel.org Received: from orbyte.nwl.cc (orbyte.nwl.cc [151.80.46.58]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2D97E212F1F for ; Wed, 2 Oct 2024 19:19:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=151.80.46.58 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727896797; cv=none; b=SPsb/FAJHN+tR6ammTd4gj1HGKGbGfB8BFOiDFnpDvbS8Nx+znWpW0wioEcBRTUN2W9jyOW4uw9N4F7CgGL0Tx5kYm+iArnJBrc/r/59ER3y10HuwURQzhgMy1uf2/AZVMt1MVX5b0J26wDLIN81tdCxJHWD5EqNUjLeRYgPqXI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727896797; c=relaxed/simple; bh=uzvB/mXhRudW9Q37tp6fJBSV4jHuuD6wUwmsESSdUMY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EL1SYvREiglRRkegfSxBcrIy0IH9dqRtIt/yOecLpHQvUI0PTdGuNHlBRAcKaxMtqRBlHx7lwploE3h9vosnuuWZxZXfYNPMz+dBLGTzCfxIcp0NQLLM2jg96XvqY1Knyf7la2fqkrdxA7kM+78z66XtPY/Xf8f+tuFX2/MPjpY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nwl.cc; spf=pass smtp.mailfrom=nwl.cc; dkim=pass (2048-bit key) header.d=nwl.cc header.i=@nwl.cc header.b=NxhfB7kX; arc=none smtp.client-ip=151.80.46.58 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nwl.cc Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nwl.cc DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nwl.cc; s=mail2022; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To: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=B+ZLFQ8ZSxflsGf9fTJti9pPMC0gMus5JFLK32eDZXo=; b=NxhfB7kX1epWfD+nEo0oFEMsS/ +QLQIrM+GcM1UtGEBcwhT+sjKRPjL3NpiP2dxr92tpg+BGmaE0Lpr5GO+3s6IAw4bO2n11vHjvo7c scED5WXfdsMGSBio9i0RE/PtoebGmLAyelIMEasKQXiu6V58dAYf9ZUWHBW3ob5iKszWTJtjRHJtE PQC0SxVz/7exxyTzTz0mHRgOs/FjhhfY4BAmTO1zjyDW6RAYOl2vNVnv5eyw0OoUsQhAoRStV1n6X d6SD7alwmf7NeY3AVQC0CaT/Ql6chJcNFBZY24RaSw/9LfRUCZgbHX/kIYSN/sfGRczS7gQatI+zE /Z529BOA==; Received: from localhost ([::1] helo=xic) by orbyte.nwl.cc with esmtp (Exim 4.97.1) (envelope-from ) id 1sw4sz-000000002lD-1jLA; Wed, 02 Oct 2024 21:19:45 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [libnftnl PATCH 2/4] utils: Add helpers for interface name wildcards Date: Wed, 2 Oct 2024 21:19:39 +0200 Message-ID: <20241002191941.8410-3-phil@nwl.cc> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241002191941.8410-1-phil@nwl.cc> References: <20241002191941.8410-1-phil@nwl.cc> Precedence: bulk X-Mailing-List: netfilter-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Support simple (suffix) wildcards in NFTNL_CHAIN_DEV(ICES) and NFTA_FLOWTABLE_HOOK_DEVS identified by non-NUL-terminated strings. Add helpers converting to and from the human-readable asterisk-suffix notation. Signed-off-by: Phil Sutter --- include/utils.h | 4 ++++ src/chain.c | 16 ++++++++++------ src/flowtable.c | 10 ++++++---- src/utils.c | 30 ++++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 10 deletions(-) diff --git a/include/utils.h b/include/utils.h index 247d99d19dd7f..c8e890eae2ffd 100644 --- a/include/utils.h +++ b/include/utils.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "config.h" @@ -83,4 +84,7 @@ int nftnl_fprintf(FILE *fpconst, const void *obj, uint32_t cmd, uint32_t type, int nftnl_set_str_attr(const char **dptr, uint32_t *flags, uint16_t attr, const void *data, uint32_t data_len); +void mnl_attr_put_ifname(struct nlmsghdr *nlh, int attr, const char *ifname); +const char *mnl_attr_get_ifname(struct nlattr *attr); + #endif diff --git a/src/chain.c b/src/chain.c index 0b68939fe21a7..830e09fcfbbb1 100644 --- a/src/chain.c +++ b/src/chain.c @@ -490,14 +490,14 @@ void nftnl_chain_nlmsg_build_payload(struct nlmsghdr *nlh, const struct nftnl_ch mnl_attr_put_u32(nlh, NFTA_HOOK_PRIORITY, htonl(c->prio)); if (c->flags & (1 << NFTNL_CHAIN_DEV)) - mnl_attr_put_strz(nlh, NFTA_HOOK_DEV, c->dev); + mnl_attr_put_ifname(nlh, NFTA_HOOK_DEV, c->dev); else if (c->flags & (1 << NFTNL_CHAIN_DEVICES)) { struct nlattr *nest_dev; nest_dev = mnl_attr_nest_start(nlh, NFTA_HOOK_DEVS); for (i = 0; i < c->dev_array_len; i++) - mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME, - c->dev_array[i]); + mnl_attr_put_ifname(nlh, NFTA_DEVICE_NAME, + c->dev_array[i]); mnl_attr_nest_end(nlh, nest_dev); } @@ -677,8 +677,10 @@ static int nftnl_chain_parse_devs(struct nlattr *nest, struct nftnl_chain *c) mnl_attr_for_each_nested(attr, nest) { if (mnl_attr_get_type(attr) != NFTA_DEVICE_NAME) goto err; - dev_array[len++] = strdup(mnl_attr_get_str(attr)); - if (len >= size) { + dev_array[len] = strdup(mnl_attr_get_ifname(attr)); + if (!dev_array[len]) + goto err; + if (++len >= size) { tmp = realloc(dev_array, size * 2 * sizeof(char *)); if (!tmp) goto err; @@ -717,7 +719,9 @@ static int nftnl_chain_parse_hook(struct nlattr *attr, struct nftnl_chain *c) c->flags |= (1 << NFTNL_CHAIN_PRIO); } if (tb[NFTA_HOOK_DEV]) { - c->dev = strdup(mnl_attr_get_str(tb[NFTA_HOOK_DEV])); + if (c->flags & (1 << NFTNL_CHAIN_DEV)) + xfree(c->dev); + c->dev = strdup(mnl_attr_get_ifname(tb[NFTA_HOOK_DEV])); if (!c->dev) return -1; c->flags |= (1 << NFTNL_CHAIN_DEV); diff --git a/src/flowtable.c b/src/flowtable.c index 41a1456bb19b2..74cffc812996c 100644 --- a/src/flowtable.c +++ b/src/flowtable.c @@ -328,8 +328,8 @@ void nftnl_flowtable_nlmsg_build_payload(struct nlmsghdr *nlh, nest_dev = mnl_attr_nest_start(nlh, NFTA_FLOWTABLE_HOOK_DEVS); for (i = 0; i < c->dev_array_len; i++) { - mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME, - c->dev_array[i]); + mnl_attr_put_ifname(nlh, NFTA_DEVICE_NAME, + c->dev_array[i]); } mnl_attr_nest_end(nlh, nest_dev); } @@ -416,8 +416,10 @@ static int nftnl_flowtable_parse_devs(struct nlattr *nest, mnl_attr_for_each_nested(attr, nest) { if (mnl_attr_get_type(attr) != NFTA_DEVICE_NAME) goto err; - dev_array[len++] = strdup(mnl_attr_get_str(attr)); - if (len >= size) { + dev_array[len] = strdup(mnl_attr_get_ifname(attr)); + if (!dev_array[len]) + goto err; + if (++len >= size) { tmp = realloc(dev_array, size * 2 * sizeof(char *)); if (!tmp) goto err; diff --git a/src/utils.c b/src/utils.c index 2f1ffd6227583..df00ce04b32ea 100644 --- a/src/utils.c +++ b/src/utils.c @@ -17,8 +17,11 @@ #include #include +#include + #include +#include #include #include @@ -150,3 +153,30 @@ int nftnl_set_str_attr(const char **dptr, uint32_t *flags, *flags |= (1 << attr); return 0; } + +void mnl_attr_put_ifname(struct nlmsghdr *nlh, int attr, const char *ifname) +{ + int len = strlen(ifname) + 1; + + if (ifname[len - 2] == '*') + len -= 2; + + mnl_attr_put(nlh, attr, len, ifname); +} + +const char *mnl_attr_get_ifname(struct nlattr *attr) +{ + size_t slen = mnl_attr_get_payload_len(attr); + const char *dev = mnl_attr_get_str(attr); + static char buf[IFNAMSIZ]; + + if (dev[slen - 1] == '\0') + return dev; + + if (slen > IFNAMSIZ - 2) + slen = IFNAMSIZ - 2; + + memcpy(buf, dev, slen); + memcpy(buf + slen, "*\0", 2); + return buf; +} From patchwork Wed Oct 2 19:19:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 1992140 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=nwl.cc header.i=@nwl.cc header.a=rsa-sha256 header.s=mail2022 header.b=LVrBKL+V; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=139.178.88.99; helo=sv.mirrors.kernel.org; envelope-from=netfilter-devel+bounces-4197-incoming=patchwork.ozlabs.org@vger.kernel.org; receiver=patchwork.ozlabs.org) Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org [139.178.88.99]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4XJl4l4J0fz1xtr for ; Thu, 3 Oct 2024 05:20:07 +1000 (AEST) Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id 5095E2855A3 for ; Wed, 2 Oct 2024 19:20:06 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A7738215F75; Wed, 2 Oct 2024 19:19:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=nwl.cc header.i=@nwl.cc header.b="LVrBKL+V" X-Original-To: netfilter-devel@vger.kernel.org Received: from orbyte.nwl.cc (orbyte.nwl.cc [151.80.46.58]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2D930212F0E for ; Wed, 2 Oct 2024 19:19:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=151.80.46.58 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727896798; cv=none; b=Lm9PL3MBzUvEGmaRnCdx4Yv/Wn5L0MSL/T1Yvk5OQds/9kBnSYA8WLpwsJmPujIDonaCdxG80DUW/D1Y+DfXgkD0OASRnKiUFgcOBWVEQjPS6mnpWJZYdWFt9aOgkACkMAPG1CtE9oiS0yVSBNPPFvcEs/QGCBFOnvk1I/JYrDA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727896798; c=relaxed/simple; bh=dwH3A2uc/P90ZwmDnKGJAxoUH3+Z9iOsh8O5q0GUomI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=q/dYaES5+dLtCV0m0PBTR6xkOod0SXRUao6EfFfSq/7oNX8t8MZrlfnlyaprEp2I+BzjDp+wJit78T9dhmFPooAUydJe7eWK1G32A/VFe7z0fffhq2WLIE2Z6fa8BOdShad0O26ZevsO6HkM9kTdzaPuqH/nRgXfw9Caj0zCXGI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nwl.cc; spf=pass smtp.mailfrom=nwl.cc; dkim=pass (2048-bit key) header.d=nwl.cc header.i=@nwl.cc header.b=LVrBKL+V; arc=none smtp.client-ip=151.80.46.58 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nwl.cc Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nwl.cc DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nwl.cc; s=mail2022; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To: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=umRZI7d5lkG1CZl5+ZeSS7YPt9xz1kvcPC4PiAkUq44=; b=LVrBKL+VjDUbR8YX00IzWRzhtT 0JQU60D5inYBHlIozWpJyxhAZ9jCu6cX/DGiKQYR9DIDxsxLrA8bSJ7FnJBZYgU96Sbla7LTWnwg9 yM+zLCTj/sefdU+htQ1e11THKadymSalMATL3BW7faljUw1bY9du4Wa3eWCwtQCaINr+y+SWICAVE vkV553mpvyq8tCitBXaoJ2mkIxO77jr52iXqDtqy3TLfwqv59PMKH/s0mMie0FLRD3+xRunknXq8s sFjzuslLSCTBa/2QlMhuzTMsmqX/A3SPhU6yOSLbFyO9D5B4U0PJXJqvY0D7somEhFpTCAKD1t5mk PGbmqryA==; Received: from localhost ([::1] helo=xic) by orbyte.nwl.cc with esmtp (Exim 4.97.1) (envelope-from ) id 1sw4sz-000000002lH-3xiv; Wed, 02 Oct 2024 21:19:46 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [libnftnl PATCH 3/4] utils: Introduce nftnl_parse_str_attr() Date: Wed, 2 Oct 2024 21:19:40 +0200 Message-ID: <20241002191941.8410-4-phil@nwl.cc> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241002191941.8410-1-phil@nwl.cc> References: <20241002191941.8410-1-phil@nwl.cc> Precedence: bulk X-Mailing-List: netfilter-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Wrap the common parsing of string attributes in a function. Apart from slightly reducing code size, this unifies callers in conditional freeing of the field in case it was set before (missing in twelve spots) and error checking for failing strdup()-calls (missing in four spots). Signed-off-by: Phil Sutter --- include/utils.h | 3 +++ src/chain.c | 33 +++++++++------------------------ src/expr/dynset.c | 12 +++++------- src/expr/flow_offload.c | 12 +++++------- src/expr/log.c | 13 ++++--------- src/expr/lookup.c | 12 +++++------- src/expr/objref.c | 18 ++++++++---------- src/flowtable.c | 24 ++++++++---------------- src/object.c | 14 ++++++-------- src/rule.c | 22 ++++++---------------- src/set.c | 22 ++++++---------------- src/set_elem.c | 38 +++++++++++++------------------------- src/table.c | 11 +++-------- src/trace.c | 28 ++++++++++------------------ src/utils.c | 15 +++++++++++++++ 15 files changed, 106 insertions(+), 171 deletions(-) diff --git a/include/utils.h b/include/utils.h index c8e890eae2ffd..8b5feba2bc659 100644 --- a/include/utils.h +++ b/include/utils.h @@ -87,4 +87,7 @@ int nftnl_set_str_attr(const char **dptr, uint32_t *flags, void mnl_attr_put_ifname(struct nlmsghdr *nlh, int attr, const char *ifname); const char *mnl_attr_get_ifname(struct nlattr *attr); +int nftnl_parse_str_attr(const struct nlattr *tb, int attr, + const char **field, uint32_t *flags); + #endif diff --git a/src/chain.c b/src/chain.c index 830e09fcfbbb1..7691975a96b5f 100644 --- a/src/chain.c +++ b/src/chain.c @@ -746,22 +746,12 @@ int nftnl_chain_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_chain *c) if (mnl_attr_parse(nlh, sizeof(*nfg), nftnl_chain_parse_attr_cb, tb) < 0) return -1; - if (tb[NFTA_CHAIN_NAME]) { - if (c->flags & (1 << NFTNL_CHAIN_NAME)) - xfree(c->name); - c->name = strdup(mnl_attr_get_str(tb[NFTA_CHAIN_NAME])); - if (!c->name) - return -1; - c->flags |= (1 << NFTNL_CHAIN_NAME); - } - if (tb[NFTA_CHAIN_TABLE]) { - if (c->flags & (1 << NFTNL_CHAIN_TABLE)) - xfree(c->table); - c->table = strdup(mnl_attr_get_str(tb[NFTA_CHAIN_TABLE])); - if (!c->table) - return -1; - c->flags |= (1 << NFTNL_CHAIN_TABLE); - } + if (nftnl_parse_str_attr(tb[NFTA_CHAIN_NAME], NFTNL_CHAIN_NAME, + &c->name, &c->flags) < 0) + return -1; + if (nftnl_parse_str_attr(tb[NFTA_CHAIN_TABLE], NFTNL_CHAIN_TABLE, + &c->table, &c->flags) < 0) + return -1; if (tb[NFTA_CHAIN_HOOK]) { ret = nftnl_chain_parse_hook(tb[NFTA_CHAIN_HOOK], c); if (ret < 0) @@ -784,14 +774,9 @@ int nftnl_chain_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_chain *c) c->handle = be64toh(mnl_attr_get_u64(tb[NFTA_CHAIN_HANDLE])); c->flags |= (1 << NFTNL_CHAIN_HANDLE); } - if (tb[NFTA_CHAIN_TYPE]) { - if (c->flags & (1 << NFTNL_CHAIN_TYPE)) - xfree(c->type); - c->type = strdup(mnl_attr_get_str(tb[NFTA_CHAIN_TYPE])); - if (!c->type) - return -1; - c->flags |= (1 << NFTNL_CHAIN_TYPE); - } + if (nftnl_parse_str_attr(tb[NFTA_CHAIN_TYPE], NFTNL_CHAIN_TYPE, + &c->type, &c->flags) < 0) + return -1; if (tb[NFTA_CHAIN_FLAGS]) { c->chain_flags = ntohl(mnl_attr_get_u32(tb[NFTA_CHAIN_FLAGS])); c->flags |= (1 << NFTNL_CHAIN_FLAGS); diff --git a/src/expr/dynset.c b/src/expr/dynset.c index 9d2bfe5e206b1..1075f52c43f7f 100644 --- a/src/expr/dynset.c +++ b/src/expr/dynset.c @@ -249,13 +249,11 @@ nftnl_expr_dynset_parse(struct nftnl_expr *e, struct nlattr *attr) dynset->timeout = be64toh(mnl_attr_get_u64(tb[NFTA_DYNSET_TIMEOUT])); e->flags |= (1 << NFTNL_EXPR_DYNSET_TIMEOUT); } - if (tb[NFTA_DYNSET_SET_NAME]) { - dynset->set_name = - strdup(mnl_attr_get_str(tb[NFTA_DYNSET_SET_NAME])); - if (!dynset->set_name) - return -1; - e->flags |= (1 << NFTNL_EXPR_DYNSET_SET_NAME); - } + if (nftnl_parse_str_attr(tb[NFTA_DYNSET_SET_NAME], + NFTNL_EXPR_DYNSET_SET_NAME, + (const char **)&dynset->set_name, + &e->flags) < 0) + return -1; if (tb[NFTA_DYNSET_SET_ID]) { dynset->set_id = ntohl(mnl_attr_get_u32(tb[NFTA_DYNSET_SET_ID])); e->flags |= (1 << NFTNL_EXPR_DYNSET_SET_ID); diff --git a/src/expr/flow_offload.c b/src/expr/flow_offload.c index 5f209a63fa960..ce22ec419a944 100644 --- a/src/expr/flow_offload.c +++ b/src/expr/flow_offload.c @@ -79,13 +79,11 @@ static int nftnl_expr_flow_parse(struct nftnl_expr *e, struct nlattr *attr) if (mnl_attr_parse_nested(attr, nftnl_expr_flow_cb, tb) < 0) return -1; - if (tb[NFTA_FLOW_TABLE_NAME]) { - flow->table_name = - strdup(mnl_attr_get_str(tb[NFTA_FLOW_TABLE_NAME])); - if (!flow->table_name) - return -1; - e->flags |= (1 << NFTNL_EXPR_FLOW_TABLE_NAME); - } + if (nftnl_parse_str_attr(tb[NFTA_FLOW_TABLE_NAME], + NFTNL_EXPR_FLOW_TABLE_NAME, + (const char **)&flow->table_name, + &e->flags) < 0) + return -1; return ret; } diff --git a/src/expr/log.c b/src/expr/log.c index 18ec2b64a5b93..0d255f7aaa475 100644 --- a/src/expr/log.c +++ b/src/expr/log.c @@ -151,15 +151,10 @@ nftnl_expr_log_parse(struct nftnl_expr *e, struct nlattr *attr) if (mnl_attr_parse_nested(attr, nftnl_expr_log_cb, tb) < 0) return -1; - if (tb[NFTA_LOG_PREFIX]) { - if (log->prefix) - xfree(log->prefix); - - log->prefix = strdup(mnl_attr_get_str(tb[NFTA_LOG_PREFIX])); - if (!log->prefix) - return -1; - e->flags |= (1 << NFTNL_EXPR_LOG_PREFIX); - } + if (nftnl_parse_str_attr(tb[NFTA_LOG_PREFIX], + NFTNL_EXPR_LOG_PREFIX, + &log->prefix, &e->flags) < 0) + return -1; if (tb[NFTA_LOG_GROUP]) { log->group = ntohs(mnl_attr_get_u16(tb[NFTA_LOG_GROUP])); e->flags |= (1 << NFTNL_EXPR_LOG_GROUP); diff --git a/src/expr/lookup.c b/src/expr/lookup.c index 21a7fcef40413..07c1539f45517 100644 --- a/src/expr/lookup.c +++ b/src/expr/lookup.c @@ -145,13 +145,11 @@ nftnl_expr_lookup_parse(struct nftnl_expr *e, struct nlattr *attr) lookup->dreg = ntohl(mnl_attr_get_u32(tb[NFTA_LOOKUP_DREG])); e->flags |= (1 << NFTNL_EXPR_LOOKUP_DREG); } - if (tb[NFTA_LOOKUP_SET]) { - lookup->set_name = - strdup(mnl_attr_get_str(tb[NFTA_LOOKUP_SET])); - if (!lookup->set_name) - return -1; - e->flags |= (1 << NFTNL_EXPR_LOOKUP_SET); - } + if (nftnl_parse_str_attr(tb[NFTA_LOOKUP_SET], + NFTNL_EXPR_LOOKUP_SET, + (const char **)&lookup->set_name, + &e->flags) < 0) + return -1; if (tb[NFTA_LOOKUP_SET_ID]) { lookup->set_id = ntohl(mnl_attr_get_u32(tb[NFTA_LOOKUP_SET_ID])); diff --git a/src/expr/objref.c b/src/expr/objref.c index 00538057222b5..76916f53c8202 100644 --- a/src/expr/objref.c +++ b/src/expr/objref.c @@ -148,21 +148,19 @@ static int nftnl_expr_objref_parse(struct nftnl_expr *e, struct nlattr *attr) ntohl(mnl_attr_get_u32(tb[NFTA_OBJREF_IMM_TYPE])); e->flags |= (1 << NFTNL_EXPR_OBJREF_IMM_TYPE); } - if (tb[NFTA_OBJREF_IMM_NAME]) { - objref->imm.name = - strdup(mnl_attr_get_str(tb[NFTA_OBJREF_IMM_NAME])); - e->flags |= (1 << NFTNL_EXPR_OBJREF_IMM_NAME); - } + if (nftnl_parse_str_attr(tb[NFTA_OBJREF_IMM_NAME], + NFTNL_EXPR_OBJREF_IMM_NAME, + &objref->imm.name, &e->flags) < 0) + return -1; if (tb[NFTA_OBJREF_SET_SREG]) { objref->set.sreg = ntohl(mnl_attr_get_u32(tb[NFTA_OBJREF_SET_SREG])); e->flags |= (1 << NFTNL_EXPR_OBJREF_SET_SREG); } - if (tb[NFTA_OBJREF_SET_NAME]) { - objref->set.name = - strdup(mnl_attr_get_str(tb[NFTA_OBJREF_SET_NAME])); - e->flags |= (1 << NFTNL_EXPR_OBJREF_SET_NAME); - } + if (nftnl_parse_str_attr(tb[NFTA_OBJREF_SET_NAME], + NFTNL_EXPR_OBJREF_SET_NAME, + &objref->set.name, &e->flags) < 0) + return -1; if (tb[NFTA_OBJREF_SET_ID]) { objref->set.id = ntohl(mnl_attr_get_u32(tb[NFTA_OBJREF_SET_ID])); diff --git a/src/flowtable.c b/src/flowtable.c index 74cffc812996c..d907f40a70089 100644 --- a/src/flowtable.c +++ b/src/flowtable.c @@ -477,22 +477,14 @@ int nftnl_flowtable_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_flowtab if (mnl_attr_parse(nlh, sizeof(*nfg), nftnl_flowtable_parse_attr_cb, tb) < 0) return -1; - if (tb[NFTA_FLOWTABLE_NAME]) { - if (c->flags & (1 << NFTNL_FLOWTABLE_NAME)) - xfree(c->name); - c->name = strdup(mnl_attr_get_str(tb[NFTA_FLOWTABLE_NAME])); - if (!c->name) - return -1; - c->flags |= (1 << NFTNL_FLOWTABLE_NAME); - } - if (tb[NFTA_FLOWTABLE_TABLE]) { - if (c->flags & (1 << NFTNL_FLOWTABLE_TABLE)) - xfree(c->table); - c->table = strdup(mnl_attr_get_str(tb[NFTA_FLOWTABLE_TABLE])); - if (!c->table) - return -1; - c->flags |= (1 << NFTNL_FLOWTABLE_TABLE); - } + if (nftnl_parse_str_attr(tb[NFTA_FLOWTABLE_NAME], + NFTNL_FLOWTABLE_NAME, + &c->name, &c->flags) < 0) + return -1; + if (nftnl_parse_str_attr(tb[NFTA_FLOWTABLE_TABLE], + NFTNL_FLOWTABLE_TABLE, + &c->table, &c->flags) < 0) + return -1; if (tb[NFTA_FLOWTABLE_HOOK]) { ret = nftnl_flowtable_parse_hook(tb[NFTA_FLOWTABLE_HOOK], c); if (ret < 0) diff --git a/src/object.c b/src/object.c index 9d150315d487d..1935879fdaa24 100644 --- a/src/object.c +++ b/src/object.c @@ -344,14 +344,12 @@ int nftnl_obj_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_obj *obj) if (mnl_attr_parse(nlh, sizeof(*nfg), nftnl_obj_parse_attr_cb, tb) < 0) return -1; - if (tb[NFTA_OBJ_TABLE]) { - obj->table = strdup(mnl_attr_get_str(tb[NFTA_OBJ_TABLE])); - obj->flags |= (1 << NFTNL_OBJ_TABLE); - } - if (tb[NFTA_OBJ_NAME]) { - obj->name = strdup(mnl_attr_get_str(tb[NFTA_OBJ_NAME])); - obj->flags |= (1 << NFTNL_OBJ_NAME); - } + if (nftnl_parse_str_attr(tb[NFTA_OBJ_TABLE], NFTNL_OBJ_TABLE, + &obj->table, &obj->flags) < 0) + return -1; + if (nftnl_parse_str_attr(tb[NFTA_OBJ_NAME], NFTNL_OBJ_NAME, + &obj->name, &obj->flags) < 0) + return -1; if (tb[NFTA_OBJ_TYPE]) { uint32_t type = ntohl(mnl_attr_get_u32(tb[NFTA_OBJ_TYPE])); diff --git a/src/rule.c b/src/rule.c index c22918a8f3527..07ca3227fac4d 100644 --- a/src/rule.c +++ b/src/rule.c @@ -435,22 +435,12 @@ int nftnl_rule_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_rule *r) if (mnl_attr_parse(nlh, sizeof(*nfg), nftnl_rule_parse_attr_cb, tb) < 0) return -1; - if (tb[NFTA_RULE_TABLE]) { - if (r->flags & (1 << NFTNL_RULE_TABLE)) - xfree(r->table); - r->table = strdup(mnl_attr_get_str(tb[NFTA_RULE_TABLE])); - if (!r->table) - return -1; - r->flags |= (1 << NFTNL_RULE_TABLE); - } - if (tb[NFTA_RULE_CHAIN]) { - if (r->flags & (1 << NFTNL_RULE_CHAIN)) - xfree(r->chain); - r->chain = strdup(mnl_attr_get_str(tb[NFTA_RULE_CHAIN])); - if (!r->chain) - return -1; - r->flags |= (1 << NFTNL_RULE_CHAIN); - } + if (nftnl_parse_str_attr(tb[NFTA_RULE_TABLE], NFTNL_RULE_TABLE, + &r->table, &r->flags) < 0) + return -1; + if (nftnl_parse_str_attr(tb[NFTA_RULE_CHAIN], NFTNL_RULE_CHAIN, + &r->chain, &r->flags) < 0) + return -1; if (tb[NFTA_RULE_HANDLE]) { r->handle = be64toh(mnl_attr_get_u64(tb[NFTA_RULE_HANDLE])); r->flags |= (1 << NFTNL_RULE_HANDLE); diff --git a/src/set.c b/src/set.c index 75ad64e038502..f3a1dd188246a 100644 --- a/src/set.c +++ b/src/set.c @@ -645,22 +645,12 @@ int nftnl_set_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_set *s) if (mnl_attr_parse(nlh, sizeof(*nfg), nftnl_set_parse_attr_cb, tb) < 0) return -1; - if (tb[NFTA_SET_TABLE]) { - if (s->flags & (1 << NFTNL_SET_TABLE)) - xfree(s->table); - s->table = strdup(mnl_attr_get_str(tb[NFTA_SET_TABLE])); - if (!s->table) - return -1; - s->flags |= (1 << NFTNL_SET_TABLE); - } - if (tb[NFTA_SET_NAME]) { - if (s->flags & (1 << NFTNL_SET_NAME)) - xfree(s->name); - s->name = strdup(mnl_attr_get_str(tb[NFTA_SET_NAME])); - if (!s->name) - return -1; - s->flags |= (1 << NFTNL_SET_NAME); - } + if (nftnl_parse_str_attr(tb[NFTA_SET_TABLE], NFTNL_SET_TABLE, + &s->table, &s->flags) < 0) + return -1; + if (nftnl_parse_str_attr(tb[NFTA_SET_NAME], NFTNL_SET_NAME, + &s->name, &s->flags) < 0) + return -1; if (tb[NFTA_SET_HANDLE]) { s->handle = be64toh(mnl_attr_get_u64(tb[NFTA_SET_HANDLE])); s->flags |= (1 << NFTNL_SET_HANDLE); diff --git a/src/set_elem.c b/src/set_elem.c index 9207a0dbd6899..7b3c01701aaee 100644 --- a/src/set_elem.c +++ b/src/set_elem.c @@ -580,13 +580,11 @@ static int nftnl_set_elems_parse2(struct nftnl_set *s, const struct nlattr *nest memcpy(e->user.data, udata, e->user.len); e->flags |= (1 << NFTNL_RULE_USERDATA); } - if (tb[NFTA_SET_ELEM_OBJREF]) { - e->objref = strdup(mnl_attr_get_str(tb[NFTA_SET_ELEM_OBJREF])); - if (e->objref == NULL) { - ret = -1; - goto out_set_elem; - } - e->flags |= (1 << NFTNL_SET_ELEM_OBJREF); + if (nftnl_parse_str_attr(tb[NFTA_SET_ELEM_OBJREF], + NFTNL_SET_ELEM_OBJREF, + &e->objref, &e->flags) < 0) { + ret = -1; + goto out_set_elem; } /* Add this new element to this set */ @@ -650,24 +648,14 @@ int nftnl_set_elems_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_set *s) nftnl_set_elem_list_parse_attr_cb, tb) < 0) return -1; - if (tb[NFTA_SET_ELEM_LIST_TABLE]) { - if (s->flags & (1 << NFTNL_SET_TABLE)) - xfree(s->table); - s->table = - strdup(mnl_attr_get_str(tb[NFTA_SET_ELEM_LIST_TABLE])); - if (!s->table) - return -1; - s->flags |= (1 << NFTNL_SET_TABLE); - } - if (tb[NFTA_SET_ELEM_LIST_SET]) { - if (s->flags & (1 << NFTNL_SET_NAME)) - xfree(s->name); - s->name = - strdup(mnl_attr_get_str(tb[NFTA_SET_ELEM_LIST_SET])); - if (!s->name) - return -1; - s->flags |= (1 << NFTNL_SET_NAME); - } + if (nftnl_parse_str_attr(tb[NFTA_SET_ELEM_LIST_TABLE], + NFTNL_SET_TABLE, + &s->table, &s->flags) < 0) + return -1; + if (nftnl_parse_str_attr(tb[NFTA_SET_ELEM_LIST_SET], + NFTNL_SET_NAME, + &s->name, &s->flags) < 0) + return -1; if (tb[NFTA_SET_ELEM_LIST_SET_ID]) { s->id = ntohl(mnl_attr_get_u32(tb[NFTA_SET_ELEM_LIST_SET_ID])); s->flags |= (1 << NFTNL_SET_ID); diff --git a/src/table.c b/src/table.c index b1b164cbbcedc..c0566b242cacf 100644 --- a/src/table.c +++ b/src/table.c @@ -289,14 +289,9 @@ int nftnl_table_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_table *t) if (mnl_attr_parse(nlh, sizeof(*nfg), nftnl_table_parse_attr_cb, tb) < 0) return -1; - if (tb[NFTA_TABLE_NAME]) { - if (t->flags & (1 << NFTNL_TABLE_NAME)) - xfree(t->name); - t->name = strdup(mnl_attr_get_str(tb[NFTA_TABLE_NAME])); - if (!t->name) - return -1; - t->flags |= (1 << NFTNL_TABLE_NAME); - } + if (nftnl_parse_str_attr(tb[NFTA_TABLE_NAME], NFTNL_TABLE_NAME, + &t->name, &t->flags) < 0) + return -1; if (tb[NFTA_TABLE_FLAGS]) { t->table_flags = ntohl(mnl_attr_get_u32(tb[NFTA_TABLE_FLAGS])); t->flags |= (1 << NFTNL_TABLE_FLAGS); diff --git a/src/trace.c b/src/trace.c index f4264377508e8..5accf12a542d5 100644 --- a/src/trace.c +++ b/src/trace.c @@ -315,11 +315,11 @@ static int nftnl_trace_parse_verdict(const struct nlattr *attr, case NFT_JUMP: if (!tb[NFTA_VERDICT_CHAIN]) abi_breakage(); - t->jump_target = strdup(mnl_attr_get_str(tb[NFTA_VERDICT_CHAIN])); - if (!t->jump_target) + if (nftnl_parse_str_attr(tb[NFTA_VERDICT_CHAIN], + NFTNL_TRACE_JUMP_TARGET, + (const char **)&t->jump_target, + &t->flags) < 0) return -1; - - t->flags |= (1 << NFTNL_TRACE_JUMP_TARGET); break; } return 0; @@ -349,21 +349,13 @@ int nftnl_trace_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_trace *t) t->id = ntohl(mnl_attr_get_u32(tb[NFTA_TRACE_ID])); t->flags |= (1 << NFTNL_TRACE_ID); - if (tb[NFTA_TRACE_TABLE]) { - t->table = strdup(mnl_attr_get_str(tb[NFTA_TRACE_TABLE])); - if (!t->table) - return -1; - - t->flags |= (1 << NFTNL_TRACE_TABLE); - } - - if (tb[NFTA_TRACE_CHAIN]) { - t->chain = strdup(mnl_attr_get_str(tb[NFTA_TRACE_CHAIN])); - if (!t->chain) - return -1; + if (nftnl_parse_str_attr(tb[NFTA_TRACE_TABLE], NFTNL_TRACE_TABLE, + (const char **)&t->table, &t->flags) < 0) + return -1; - t->flags |= (1 << NFTNL_TRACE_CHAIN); - } + if (nftnl_parse_str_attr(tb[NFTA_TRACE_CHAIN], NFTNL_TRACE_CHAIN, + (const char **)&t->chain, &t->flags) < 0) + return -1; if (tb[NFTA_TRACE_IIFTYPE]) { t->iiftype = ntohs(mnl_attr_get_u16(tb[NFTA_TRACE_IIFTYPE])); diff --git a/src/utils.c b/src/utils.c index df00ce04b32ea..fdf662778e826 100644 --- a/src/utils.c +++ b/src/utils.c @@ -180,3 +180,18 @@ const char *mnl_attr_get_ifname(struct nlattr *attr) memcpy(buf + slen, "*\0", 2); return buf; } + +int nftnl_parse_str_attr(const struct nlattr *tb, int attr, + const char **field, uint32_t *flags) +{ + if (!tb) + return 0; + + if (*flags & (1 << attr)) + xfree(*field); + *field = strdup(mnl_attr_get_str(tb)); + if (!*field) + return -1; + *flags |= (1 << attr); + return 0; +} From patchwork Wed Oct 2 19:19:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 1992142 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=nwl.cc header.i=@nwl.cc header.a=rsa-sha256 header.s=mail2022 header.b=NC2ttCCZ; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=147.75.80.249; helo=am.mirrors.kernel.org; envelope-from=netfilter-devel+bounces-4198-incoming=patchwork.ozlabs.org@vger.kernel.org; receiver=patchwork.ozlabs.org) Received: from am.mirrors.kernel.org (am.mirrors.kernel.org [147.75.80.249]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4XJl4q36Ncz1xtY for ; Thu, 3 Oct 2024 05:20:11 +1000 (AEST) Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 9B6941F22659 for ; Wed, 2 Oct 2024 19:20:08 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E733B212F0E; Wed, 2 Oct 2024 19:19:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=nwl.cc header.i=@nwl.cc header.b="NC2ttCCZ" X-Original-To: netfilter-devel@vger.kernel.org Received: from orbyte.nwl.cc (orbyte.nwl.cc [151.80.46.58]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 93FC92141A9 for ; Wed, 2 Oct 2024 19:19:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=151.80.46.58 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727896798; cv=none; b=VGe4jMQ2iEl/Yr0lq7O2Kh/OG5OnsiFXRoT3QfhDDXnWD5zZ6wpZMWIt8RvNt4Dmd8Mu3PbENsfR7XlVaOdtGfTG+NQne4c141i6mg4nfjk3Qv7PB4wYhsVDsDsyxeO3mr8KqCrlvDjkxnCU1LkLVotQg/4hHhx6CHbW0akfoiQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727896798; c=relaxed/simple; bh=kpRrN1qY6GMSb0rXhCvnKpcsf3KxCYOOdizFchH5whc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KqguBlZV45b428X2XhYD5ACQfW/S0qaq9aLRlKAET3U1AezQPTJ4t0A/rrEJFDpzr5sueZwOAU0y1KNWWj/r41On8wCOOaTmzOaCC14WYZQ9EjBdel1ldKF4Usj2PL/grqsFVaOffiCAfniIVxnv4EcnrRwTYjcInD1UtQEZQ4Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nwl.cc; spf=pass smtp.mailfrom=nwl.cc; dkim=pass (2048-bit key) header.d=nwl.cc header.i=@nwl.cc header.b=NC2ttCCZ; arc=none smtp.client-ip=151.80.46.58 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=nwl.cc Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nwl.cc DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nwl.cc; s=mail2022; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To: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=PocHrGFdIylDbV+P3DN+ITckVII2u9TMfQJh2YW2+2k=; b=NC2ttCCZRYayGfReRdSoRdeAt+ +iXDBsr6AlbqB0gUemoLRkip0KaeD2FNmaLpUqIrsift+1bXpt2UKr1jc0+OpUk/ZLqVLqaYGb+jC Pmswi7ULrI/QyMkjFRS19DnN28VT3UxrthKNbhhNY32iZQVUGhbzE3lIZUSopp1B3KvXHS+BQychy bADjdlr1Gpt0+AbvUt4VALsWcuwkgLRWEy1LMGulkl6gZ4z4Jhd9JZdLZStJLGne/uHarZBopP7I+ Hr/3/LHY/sw8qqFNSgO9bpYJKATsEsWixlGASiFUi3RyQriu30SWmkLw5UDSLxVEl74gMmMdMp0pE M3WTD8AQ==; Received: from localhost ([::1] helo=xic) by orbyte.nwl.cc with esmtp (Exim 4.97.1) (envelope-from ) id 1sw4t1-000000002lY-2lSv; Wed, 02 Oct 2024 21:19:47 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [libnftnl PATCH 4/4] device: Introduce nftnl_device Date: Wed, 2 Oct 2024 21:19:41 +0200 Message-ID: <20241002191941.8410-5-phil@nwl.cc> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241002191941.8410-1-phil@nwl.cc> References: <20241002191941.8410-1-phil@nwl.cc> Precedence: bulk X-Mailing-List: netfilter-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 A data structure used to parse NFT_MSG_(NEW|DEL)DEV messages into. Since the kernel does not support these message types in requests yet, implement a parser and getters only. Signed-off-by: Phil Sutter --- include/libnftnl/Makefile.am | 1 + include/libnftnl/device.h | 39 +++++++ include/linux/netfilter/nf_tables.h | 8 ++ src/Makefile.am | 1 + src/device.c | 153 ++++++++++++++++++++++++++++ src/libnftnl.map | 10 ++ 6 files changed, 212 insertions(+) create mode 100644 include/libnftnl/device.h create mode 100644 src/device.c diff --git a/include/libnftnl/Makefile.am b/include/libnftnl/Makefile.am index d846a574f4386..feaa7285f0070 100644 --- a/include/libnftnl/Makefile.am +++ b/include/libnftnl/Makefile.am @@ -2,6 +2,7 @@ pkginclude_HEADERS = batch.h \ table.h \ trace.h \ chain.h \ + device.h \ object.h \ rule.h \ expr.h \ diff --git a/include/libnftnl/device.h b/include/libnftnl/device.h new file mode 100644 index 0000000000000..8c437a1fe3ccf --- /dev/null +++ b/include/libnftnl/device.h @@ -0,0 +1,39 @@ +#ifndef _LIBNFTNL_DEVICE_H_ +#define _LIBNFTNL_DEVICE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +struct nftnl_device; + +struct nftnl_device *nftnl_device_alloc(void); +void nftnl_device_free(const struct nftnl_device *); + +enum nftnl_device_attr { + NFTNL_DEVICE_NAME = 0, + NFTNL_DEVICE_TABLE, + NFTNL_DEVICE_FLOWTABLE, + NFTNL_DEVICE_CHAIN, + NFTNL_DEVICE_SPEC, + NFTNL_DEVICE_FAMILY, + __NFTNL_DEVICE_MAX, +}; +#define NFTNL_DEVICE_MAX (__NFTNL_DEVICE_MAX - 1) + +bool nftnl_device_is_set(const struct nftnl_device *d, uint16_t attr); + +const void *nftnl_device_get_data(const struct nftnl_device *d, + uint16_t attr, uint32_t *data_len); +const char *nftnl_device_get_str(const struct nftnl_device *d, uint16_t attr); +int32_t nftnl_device_get_s32(const struct nftnl_device *d, uint16_t attr); + +struct nlmsghdr; + +int nftnl_device_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_device *d); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* _LIBNFTNL_DEVICE_H_ */ diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index c48b19333630d..2f73d367cf429 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -1740,10 +1740,18 @@ enum nft_synproxy_attributes { * enum nft_device_attributes - nf_tables device netlink attributes * * @NFTA_DEVICE_NAME: name of this device (NLA_STRING) + * @NFTA_DEVICE_TABLE: table containing the flowtable or chain hooking into the device (NLA_STRING) + * @NFTA_DEVICE_FLOWTABLE: flowtable hooking into the device (NLA_STRING) + * @NFTA_DEVICE_CHAIN: chain hooking into the device (NLA_STRING) + * @NFTA_DEVICE_SPEC: hook spec matching the device (NLA_STRING) */ enum nft_devices_attributes { NFTA_DEVICE_UNSPEC, NFTA_DEVICE_NAME, + NFTA_DEVICE_TABLE, + NFTA_DEVICE_FLOWTABLE, + NFTA_DEVICE_CHAIN, + NFTA_DEVICE_SPEC, __NFTA_DEVICE_MAX }; #define NFTA_DEVICE_MAX (__NFTA_DEVICE_MAX - 1) diff --git a/src/Makefile.am b/src/Makefile.am index 3cd259c04d1c3..34dbe7ced1a2a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,6 +13,7 @@ libnftnl_la_SOURCES = utils.c \ table.c \ trace.c \ chain.c \ + device.c \ object.c \ rule.c \ set.c \ diff --git a/src/device.c b/src/device.c new file mode 100644 index 0000000000000..79102f34752ea --- /dev/null +++ b/src/device.c @@ -0,0 +1,153 @@ +/* + * (C) 2024 Red Hat GmbH + * Author: Phil Sutter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include "internal.h" + +#include + +#include + +struct nftnl_device { + const char *name; + const char *table; + const char *flowtable; + const char *chain; + const char *spec; + int32_t family; + uint32_t flags; +}; + +EXPORT_SYMBOL(nftnl_device_alloc); +struct nftnl_device *nftnl_device_alloc(void) +{ + return calloc(1, sizeof(struct nftnl_device)); +} + +EXPORT_SYMBOL(nftnl_device_free); +void nftnl_device_free(const struct nftnl_device *d) +{ + if (d->flags & (1 << NFTNL_DEVICE_NAME)) + xfree(d->name); + if (d->flags & (1 << NFTNL_DEVICE_TABLE)) + xfree(d->table); + if (d->flags & (1 << NFTNL_DEVICE_FLOWTABLE)) + xfree(d->flowtable); + if (d->flags & (1 << NFTNL_DEVICE_CHAIN)) + xfree(d->chain); + if (d->flags & (1 << NFTNL_DEVICE_SPEC)) + xfree(d->spec); + xfree(d); +} + +EXPORT_SYMBOL(nftnl_device_is_set); +bool nftnl_device_is_set(const struct nftnl_device *d, uint16_t attr) +{ + return d->flags & (1 << attr); +} + +EXPORT_SYMBOL(nftnl_device_get_data); +const void *nftnl_device_get_data(const struct nftnl_device *d, + uint16_t attr, uint32_t *data_len) +{ + if (!(d->flags & (1 << attr))) + return NULL; + + switch (attr) { + case NFTNL_DEVICE_NAME: + *data_len = strlen(d->name) + 1; + return d->name; + case NFTNL_DEVICE_TABLE: + *data_len = strlen(d->table) + 1; + return d->table; + case NFTNL_DEVICE_FLOWTABLE: + *data_len = strlen(d->flowtable) + 1; + return d->flowtable; + case NFTNL_DEVICE_CHAIN: + *data_len = strlen(d->chain) + 1; + return d->chain; + case NFTNL_DEVICE_SPEC: + *data_len = strlen(d->spec) + 1; + return d->spec; + case NFTNL_DEVICE_FAMILY: + *data_len = sizeof(int32_t); + return &d->family; + } + return NULL; +} + +EXPORT_SYMBOL(nftnl_device_get_str); +const char *nftnl_device_get_str(const struct nftnl_device *d, uint16_t attr) +{ + uint32_t data_len; + + return nftnl_device_get_data(d, attr, &data_len); +} + +EXPORT_SYMBOL(nftnl_device_get_s32); +int32_t nftnl_device_get_s32(const struct nftnl_device *d, uint16_t attr) +{ + uint32_t data_len = 0; + const int32_t *val = nftnl_device_get_data(d, attr, &data_len); + + nftnl_assert(val, attr, data_len == sizeof(int32_t)); + + return val ? *val : 0; +} + +static int nftnl_device_parse_attr_cb(const struct nlattr *attr, void *data) +{ + const struct nlattr **tb = data; + int type = mnl_attr_get_type(attr); + + if (mnl_attr_type_valid(attr, NFTA_DEVICE_MAX) < 0) + return MNL_CB_OK; + + /* all attributes are of string type */ + if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) + abi_breakage(); + + tb[type] = attr; + return MNL_CB_OK; +} + +EXPORT_SYMBOL(nftnl_device_nlmsg_parse); +int nftnl_device_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_device *d) +{ + struct nlattr *tb[NFTA_DEVICE_MAX + 1] = {}; + struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh); + int ret = 0; + + if (mnl_attr_parse(nlh, sizeof(*nfg), nftnl_device_parse_attr_cb, tb) < 0) + return -1; + + if (nftnl_parse_str_attr(tb[NFTA_DEVICE_NAME], NFTNL_DEVICE_NAME, + &d->name, &d->flags) < 0) + return -1; + if (nftnl_parse_str_attr(tb[NFTA_DEVICE_TABLE], NFTNL_DEVICE_TABLE, + &d->table, &d->flags) < 0) + return -1; + if (nftnl_parse_str_attr(tb[NFTA_DEVICE_FLOWTABLE], + NFTNL_DEVICE_FLOWTABLE, + &d->flowtable, &d->flags) < 0) + return -1; + if (nftnl_parse_str_attr(tb[NFTA_DEVICE_CHAIN], NFTNL_DEVICE_CHAIN, + &d->chain, &d->flags) < 0) + return -1; + if (tb[NFTA_DEVICE_SPEC]) { + d->spec = strdup(mnl_attr_get_ifname(tb[NFTA_DEVICE_SPEC])); + if (!d->spec) + return -1; + d->flags |= (1 << NFTNL_DEVICE_SPEC); + } + + d->family = nfg->nfgen_family; + d->flags |= (1 << NFTNL_DEVICE_FAMILY); + + return ret; +} diff --git a/src/libnftnl.map b/src/libnftnl.map index 8fffff19eb2e2..96ee683fb0611 100644 --- a/src/libnftnl.map +++ b/src/libnftnl.map @@ -383,3 +383,13 @@ LIBNFTNL_16 { LIBNFTNL_17 { nftnl_set_elem_nlmsg_build; } LIBNFTNL_16; + +LIBNFTNL_18 { + nftnl_device_alloc; + nftnl_device_free; + nftnl_device_is_set; + nftnl_device_get_data; + nftnl_device_get_str; + nftnl_device_get_s32; + nftnl_device_nlmsg_parse; +} LIBNFTNL_17;