From patchwork Fri Sep 25 12:49:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Sennikovsky X-Patchwork-Id: 1371258 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=cloud.ionos.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=cloud.ionos.com header.i=@cloud.ionos.com header.a=rsa-sha256 header.s=google header.b=Rn2j/7Oz; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4ByWvv4rYXz9sTr for ; Fri, 25 Sep 2020 22:49:47 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728934AbgIYMto (ORCPT ); Fri, 25 Sep 2020 08:49:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38342 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728933AbgIYMtn (ORCPT ); Fri, 25 Sep 2020 08:49:43 -0400 Received: from mail-ed1-x532.google.com (mail-ed1-x532.google.com [IPv6:2a00:1450:4864:20::532]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8107AC0613CE for ; Fri, 25 Sep 2020 05:49:43 -0700 (PDT) Received: by mail-ed1-x532.google.com with SMTP id k14so2380016edo.1 for ; Fri, 25 Sep 2020 05:49:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloud.ionos.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6xkaM1Q+vQK4k5nAwBVmSYiuGGzUlZKoXx1C104qRyQ=; b=Rn2j/7Ozn+bvkgMMBXYFcFNNe/i8Vdr99oMoXhPU7KMpGKgy7CxyM8XR+5sDbk6r2H xxvI/5OC41Vpi3GqZRGHNjyEYeIfvtaPi0uvxjHsrsu4377i0FR6D3X6xoiw6/e9UJqW uPYWZRHG/m/oGGwlt7Y8Kqftc33W+dL3JV/HFAa8HolNzlkiD9tRPtaEsaY0r8wAjh9m mqcS5MRLq7yRQJCrXb/75ERjMchMOVPZsp7YPEDtkcuxkbjuNT8paXNWJU1Cog73rk6D 69TSjpMhA4eBGcKnL5NVMM8EGmSM2z0pWvr88r9kY6TTmCke7NMd0dArJATijAiNgrme CgXA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6xkaM1Q+vQK4k5nAwBVmSYiuGGzUlZKoXx1C104qRyQ=; b=qIA8kpCd6J1WhQiiFf5YekXsyowVJb9YdzZ6WE6CLIlzbv8H+hj/zG/GOFalCXQ1rc jcQ/jC0m77NJEYAWF3bjpG5LPkqJElOkQaVY3BY4ghvjBB1kyrUFidAdsdhCPn/zOUVP 8F2sbFTdJt+rxs7kyeM6NnFRga8vzRVcSGMNyc9V0N4dUHWtjk4VRgKHnWSUWGMdoEKp 2Xusmw2yhnk6WUwxWQdjnM4qSD76YuGMj0W2FtDV2N5YAg96WitdDJ60lQcjs09wkvYY ege/OJSWldbQzLBr00c8KiuXlvBV9tO0rKx8VYkou4Wb3gjzmfH1IAyHa9sLcuzh9S7A SYjQ== X-Gm-Message-State: AOAM532Zy18Vl8t6FKdIqZfb2HQMeHfNSjn6myHiMpwCIw2hJKwTj0x5 cHhvMKAYXVy5oTun1OBukwm9w4VKLSIAdA== X-Google-Smtp-Source: ABdhPJw6UuO8r8kpL2pFHmiT8095Wbe1tL6TpUw8aazceRvJtu/l0HUAtrncdRhuJnFlvtFX2rqf3Q== X-Received: by 2002:aa7:d417:: with SMTP id z23mr1115297edq.62.1601038181941; Fri, 25 Sep 2020 05:49:41 -0700 (PDT) Received: from localhost.localdomain (dynamic-046-114-037-141.46.114.pool.telefonica.de. [46.114.37.141]) by smtp.gmail.com with ESMTPSA id t3sm1761642edv.59.2020.09.25.05.49.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Sep 2020 05:49:41 -0700 (PDT) From: Mikhail Sennikovsky To: netfilter-devel@vger.kernel.org Cc: Mikhail Sennikovsky Subject: [PATCH 1/8] tests: icmp entry create/delete Date: Fri, 25 Sep 2020 14:49:12 +0200 Message-Id: <20200925124919.9389-2-mikhail.sennikovskii@cloud.ionos.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200925124919.9389-1-mikhail.sennikovskii@cloud.ionos.com> References: <20200925124919.9389-1-mikhail.sennikovskii@cloud.ionos.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Add test to cover icmp entry creation/deletion with conntrack Signed-off-by: Mikhail Sennikovsky --- tests/conntrack/testsuite/00create | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/conntrack/testsuite/00create b/tests/conntrack/testsuite/00create index 4e55a7b..911e711 100644 --- a/tests/conntrack/testsuite/00create +++ b/tests/conntrack/testsuite/00create @@ -30,3 +30,7 @@ -D -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK # mismatched address family -I -s 2001:DB8::1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +# creae icmp ping request entry +-I -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK +# delete icmp ping request entry +-D -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK From patchwork Fri Sep 25 12:49:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Sennikovsky X-Patchwork-Id: 1371276 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=cloud.ionos.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=cloud.ionos.com header.i=@cloud.ionos.com header.a=rsa-sha256 header.s=google header.b=Xv4gqdDx; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4ByX5f4NQyz9sVW for ; Fri, 25 Sep 2020 22:58:14 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728942AbgIYM6N (ORCPT ); Fri, 25 Sep 2020 08:58:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38346 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728935AbgIYMto (ORCPT ); Fri, 25 Sep 2020 08:49:44 -0400 Received: from mail-ej1-x644.google.com (mail-ej1-x644.google.com [IPv6:2a00:1450:4864:20::644]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 65662C0613CE for ; Fri, 25 Sep 2020 05:49:44 -0700 (PDT) Received: by mail-ej1-x644.google.com with SMTP id gx22so3471551ejb.5 for ; Fri, 25 Sep 2020 05:49:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloud.ionos.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ajUra2Bcick3BoFwzcMScJaNF9h4s1nfoGoG3nDAgAg=; b=Xv4gqdDxIYMupiO1PIhj626LmrOKJmhum2IutfPJEDNpWhvhtKIGShYh6QqsOyu+CY zcwwKptrXzEHfM9zV87yWrUWrClV4OF/0kQ5cvOyn5ViMgp+fxduwa9KmirXKPBWvLpc n1LQzBbSTsxno7y9EKaPbsllOFNDrU4Gdsb5wvSboVJ4/qNK6p6ZuR9jIljj7wXjZF2Z siYLc/H7ts/g3A8yPYW2yPWpKbs6Gn0GKLCjc3cMEUgOzizM5hLUa0ETxyshG+UCkSQ/ pHiJ/I1BU+jxrRq5B1uLRicUpDcXSE+G+BsudC1zf1rEZuK0Tr1mMZWQedz9Idzb/pfb mHmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ajUra2Bcick3BoFwzcMScJaNF9h4s1nfoGoG3nDAgAg=; b=s8edCWYn37CwfuvoBwwoAawFCEyTr0qUAJt4MWFFzNHNTz73m9yr+NOPYQGwENsvE/ xDAfo/JkV9bcuUHyI00Rpe6tlaJzhNyprX9mP1VPlKJj3vlFCCKnDSowExUfV3/IgOjc LFm44pPUBzeyL+7GY3No74/Q9flHbFA8qLM+ku1zCo6R6JYdyCUEZuuDx7c/eRKxMRvs pBoz35xPPvBQW5MkLoO6+E7zRTbzF6GveRuZAX/ZqtMk8cvbangjXCnbth2z3L9oBVrx hMtZ3F9htJT6Eg7TYdito1gNPZu5fb1v/CSmev3/MMiPyrHXlZr96YkUwUwqwdvg2Fs1 ZLmw== X-Gm-Message-State: AOAM531iXl6PDHoe05e4IJMSbHcsjgE1HcQh1q5RHbhRChCHmkaidig5 fLgKqFB2ZqcI9GO0qVSsjjqoMmXOCaL2qQ== X-Google-Smtp-Source: ABdhPJzy6C2owtoe+wuZrllhmDFHBYcinLShkjVS/MF9JYA9DalWOS3y0uTq/0qQbgBwFVuWfvrpCw== X-Received: by 2002:a17:906:b053:: with SMTP id bj19mr2462813ejb.146.1601038182889; Fri, 25 Sep 2020 05:49:42 -0700 (PDT) Received: from localhost.localdomain (dynamic-046-114-037-141.46.114.pool.telefonica.de. [46.114.37.141]) by smtp.gmail.com with ESMTPSA id t3sm1761642edv.59.2020.09.25.05.49.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Sep 2020 05:49:42 -0700 (PDT) From: Mikhail Sennikovsky To: netfilter-devel@vger.kernel.org Cc: Mikhail Sennikovsky Subject: [PATCH 2/8] conntrack: fix icmp entry creation Date: Fri, 25 Sep 2020 14:49:13 +0200 Message-Id: <20200925124919.9389-3-mikhail.sennikovskii@cloud.ionos.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200925124919.9389-1-mikhail.sennikovskii@cloud.ionos.com> References: <20200925124919.9389-1-mikhail.sennikovskii@cloud.ionos.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Creating icmp ct entry with command like conntrack -I -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 \ -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 results in nfct_query( NFCT_Q_CREATE ) request would fail because reply L4 proto is not set while having reply data specified Set reply L4 proto when reply data is given for the icmp ct entry Signed-off-by: Mikhail Sennikovsky --- extensions/libct_proto_icmp.c | 18 ++++++++++++++++++ extensions/libct_proto_icmpv6.c | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/extensions/libct_proto_icmp.c b/extensions/libct_proto_icmp.c index 2ce1c65..16c2e2e 100644 --- a/extensions/libct_proto_icmp.c +++ b/extensions/libct_proto_icmp.c @@ -78,18 +78,36 @@ static int parse(char c, tmp = atoi(optarg); nfct_set_attr_u8(ct, ATTR_ICMP_TYPE, tmp); nfct_set_attr_u8(ct, ATTR_L4PROTO, IPPROTO_ICMP); + /* + * need to set the reply proto, otherwise the + * NFCT_Q_CREATE call would fail + */ + if (nfct_attr_is_set(ct, ATTR_REPL_L3PROTO)) + nfct_set_attr_u8(ct, ATTR_REPL_L4PROTO, IPPROTO_ICMP); *flags |= CT_ICMP_TYPE; break; case '2': tmp = atoi(optarg); nfct_set_attr_u8(ct, ATTR_ICMP_CODE, tmp); nfct_set_attr_u8(ct, ATTR_L4PROTO, IPPROTO_ICMP); + /* + * need to set the reply proto, otherwise the + * NFCT_Q_CREATE call would fail + */ + if (nfct_attr_is_set(ct, ATTR_REPL_L3PROTO)) + nfct_set_attr_u8(ct, ATTR_REPL_L4PROTO, IPPROTO_ICMP); *flags |= CT_ICMP_CODE; break; case '3': id = htons(atoi(optarg)); nfct_set_attr_u16(ct, ATTR_ICMP_ID, id); nfct_set_attr_u8(ct, ATTR_L4PROTO, IPPROTO_ICMP); + /* + * need to set the reply proto, otherwise the + * NFCT_Q_CREATE call would fail + */ + if (nfct_attr_is_set(ct, ATTR_REPL_L3PROTO)) + nfct_set_attr_u8(ct, ATTR_REPL_L4PROTO, IPPROTO_ICMP); *flags |= CT_ICMP_ID; break; } diff --git a/extensions/libct_proto_icmpv6.c b/extensions/libct_proto_icmpv6.c index 18dd3e5..7f5e637 100644 --- a/extensions/libct_proto_icmpv6.c +++ b/extensions/libct_proto_icmpv6.c @@ -81,18 +81,36 @@ static int parse(char c, tmp = atoi(optarg); nfct_set_attr_u8(ct, ATTR_ICMP_TYPE, tmp); nfct_set_attr_u8(ct, ATTR_L4PROTO, IPPROTO_ICMPV6); + /* + * need to set the reply proto, otherwise the + * NFCT_Q_CREATE call would fail + */ + if (nfct_attr_is_set(ct, ATTR_REPL_L3PROTO)) + nfct_set_attr_u8(ct, ATTR_REPL_L4PROTO, IPPROTO_ICMPV6); *flags |= CT_ICMP_TYPE; break; case '2': tmp = atoi(optarg); nfct_set_attr_u8(ct, ATTR_ICMP_CODE, tmp); nfct_set_attr_u8(ct, ATTR_L4PROTO, IPPROTO_ICMPV6); + /* + * need to set the reply proto, otherwise the + * NFCT_Q_CREATE call would fail + */ + if (nfct_attr_is_set(ct, ATTR_REPL_L3PROTO)) + nfct_set_attr_u8(ct, ATTR_REPL_L4PROTO, IPPROTO_ICMPV6); *flags |= CT_ICMP_CODE; break; case '3': id = htons(atoi(optarg)); nfct_set_attr_u16(ct, ATTR_ICMP_ID, id); nfct_set_attr_u8(ct, ATTR_L4PROTO, IPPROTO_ICMPV6); + /* + * need to set the reply proto, otherwise the + * NFCT_Q_CREATE call would fail + */ + if (nfct_attr_is_set(ct, ATTR_REPL_L3PROTO)) + nfct_set_attr_u8(ct, ATTR_REPL_L4PROTO, IPPROTO_ICMPV6); *flags |= CT_ICMP_ID; break; } From patchwork Fri Sep 25 12:49:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Mikhail Sennikovsky X-Patchwork-Id: 1371275 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=cloud.ionos.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=cloud.ionos.com header.i=@cloud.ionos.com header.a=rsa-sha256 header.s=google header.b=PLQmC5k/; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4ByX5d5Tjzz9sWj for ; Fri, 25 Sep 2020 22:58:13 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729626AbgIYM6M (ORCPT ); Fri, 25 Sep 2020 08:58:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38352 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728942AbgIYMtp (ORCPT ); Fri, 25 Sep 2020 08:49:45 -0400 Received: from mail-ej1-x644.google.com (mail-ej1-x644.google.com [IPv6:2a00:1450:4864:20::644]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 709E1C0613CE for ; Fri, 25 Sep 2020 05:49:45 -0700 (PDT) Received: by mail-ej1-x644.google.com with SMTP id i26so3415544ejb.12 for ; Fri, 25 Sep 2020 05:49:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloud.ionos.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=PZ9dxGnGnQosRgPh7WRMmql4CWxYsk3ROuZQTo0fLWo=; b=PLQmC5k/gUcXtk46wNVmoKtz1mQF7SvUy7e3noG+1n69W9QUYZI42H4at1/IQyaS6w OCSL3fJ3j/v/WQc6bM6EflQrTH9ZQ2yiOilqrYARS2VwnAxG3mE2cIcFPiRmwGVC0mq7 uYdhXS/CXtipLsQpf2jt+r0C8/YtXIvNMPS4dyt0Ni8xe5NrtCyUC3BurSzn7IcBOwd6 /IRGHr+sLmI7FZwYRxFztTlWZcA9LvNUtP36xapvcvChNlM5HVEGD0YoPfjIU2yxF0L5 8uaXQCB4pPCFxSc24Z4ijDKaBNTAjYJBY9O0PtsExPoBjF1I1UcqtIee5QQI7ECn7Au0 iBpw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PZ9dxGnGnQosRgPh7WRMmql4CWxYsk3ROuZQTo0fLWo=; b=CobOBQwpMVCaRo9FlGxSKlj2LTJImZjugnW3ijOBHoSedFDDa47kOES33+Qvt8pzwU X2YGIDWMqrAma+WJFdeB1yCz4BJLSyIB+pNt+kiWJ5dFtOfXj9GLvTO/GuTgl96qHw7i WygGiunIoQsS7nQ+KeNRSKUNzv1yHHZErsaGQspuvSU14wW5zSzwU7TYREW+hz2/M8iB Dgi2G2GccNVZyozaJ1dU6x+IwlrEMMN3HrY3PItswskOTD6JJSCN9LoZ4foCGuu179Gt A9s3JFXGmsP1N77jR3pUUSKknxuFoq5y/xOyPsutC9Ehcyv+92N4luTgJXq4kiqKuRjh PtmQ== X-Gm-Message-State: AOAM531OmStyMN08418TbtzQ9A22hcI7tsKo5SFWB7ynOOh1it8xuDLV +gO4Jyf4psZTpQs6dLBYnEZ85yf7472+3A== X-Google-Smtp-Source: ABdhPJyjE0brKakFTJU3r4d5F/wynfCFi4JIWPegxbnn3BPZOC5ZC91FsuqCDtkoDIcnTYIaihj5Mg== X-Received: by 2002:a17:906:6ce:: with SMTP id v14mr2446815ejb.451.1601038183775; Fri, 25 Sep 2020 05:49:43 -0700 (PDT) Received: from localhost.localdomain (dynamic-046-114-037-141.46.114.pool.telefonica.de. [46.114.37.141]) by smtp.gmail.com with ESMTPSA id t3sm1761642edv.59.2020.09.25.05.49.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Sep 2020 05:49:43 -0700 (PDT) From: Mikhail Sennikovsky To: netfilter-devel@vger.kernel.org Cc: Mikhail Sennikovsky Subject: [PATCH 3/8] conntrack: accept parameters from stdin Date: Fri, 25 Sep 2020 14:49:14 +0200 Message-Id: <20200925124919.9389-4-mikhail.sennikovskii@cloud.ionos.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200925124919.9389-1-mikhail.sennikovskii@cloud.ionos.com> References: <20200925124919.9389-1-mikhail.sennikovskii@cloud.ionos.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org This commit allows accepting multiple sets of ct entry-related parameters on stdin. This is useful when one needs to add/update/delete a large set of ct entries with a single conntrack tool invocation. Expected syntax is "conntrack [-I|-D|-U] [table] -". When invoked like that, conntrack expects ct entry parameters to be passed to the stdin, each line presenting a separate parameter set. Signed-off-by: Mikhail Sennikovsky --- src/conntrack.c | 196 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 161 insertions(+), 35 deletions(-) diff --git a/src/conntrack.c b/src/conntrack.c index a26fa60..5834f2d 100644 --- a/src/conntrack.c +++ b/src/conntrack.c @@ -96,15 +96,18 @@ static struct { struct nfct_bitmask *label_modify; } tmpl; +int cur_argc; +char **cur_argv; + static int alloc_tmpl_objects(void) { + memset(&tmpl, 0, sizeof(tmpl)); + tmpl.ct = nfct_new(); tmpl.exptuple = nfct_new(); tmpl.mask = nfct_new(); tmpl.exp = nfexp_new(); - memset(&tmpl.mark, 0, sizeof(tmpl.mark)); - return tmpl.ct != NULL && tmpl.exptuple != NULL && tmpl.mask != NULL && tmpl.exp != NULL; } @@ -685,12 +688,18 @@ static void free_options(void) void __attribute__((noreturn)) exit_error(enum exittype status, const char *msg, ...) { + int i; va_list args; free_options(); va_start(args, msg); fprintf(stderr,"%s v%s (conntrack-tools): ", PROGNAME, VERSION); vfprintf(stderr, msg, args); + if (cur_argc) { + fprintf(stderr, "\nargs:"); + for (i = 1; i < cur_argc; ++i) + fprintf(stderr, " %s", cur_argv[i]); + } fprintf(stderr, "\n"); va_end(args); if (status == PARAMETER_PROBLEM) @@ -2317,23 +2326,63 @@ nfct_set_nat_details(const int opt, struct nf_conntrack *ct, nfct_set_attr_u16(ct, ATTR_DNAT_PORT, ntohs((uint16_t)atoi(port_str))); } +} + +static int line_to_argcv(char *cmd, char *line, char ***pargv, size_t *pargv_size) +{ + char *arg; + int argc; + char **argv = *pargv; + size_t argv_size = *pargv_size; + int argc_max = argv_size / sizeof(*argv); + +#define _ARG_ADD(_arg) do { \ + if (argc == argc_max) { \ + argc_max += 20; \ + argv_size = argc_max * sizeof (argv[0]); \ + argv = realloc(argv, argv_size); \ + if (!argv) \ + exit_error(OTHER_PROBLEM, "out of memory"); \ + } \ + argv[argc] = _arg; \ + ++argc; \ +} while (0) + +#define _ARG_SEP " \t\n\r" + for (argc = 0, arg = strtok (line, _ARG_SEP); + arg; + arg = strtok (NULL, _ARG_SEP)) { + /* + * getopt_long expects argv[0] to be the command name, + * and would always skip it so we need to include it here + */ + if (!argc && cmd) + _ARG_ADD(cmd); + _ARG_ADD(arg); + } + +#undef _ARG_ADD +#undef _ARG_SEP + *pargv = argv; + *pargv_size = argv_size; + + return argc; } int main(int argc, char *argv[]) { int c, cmd; - unsigned int type = 0, event_mask = 0, l4flags = 0, status = 0; + unsigned int type = 0, event_mask = 0, l4flags, status = 0; int res = 0, partial; - size_t socketbuffersize = 0; - int family = AF_UNSPEC; - int protonum = 0; + size_t socketbuffersize; + int family; + int protonum; union ct_address ad; unsigned int command = 0; - - /* we release these objects in the exit_error() path. */ - if (!alloc_tmpl_objects()) - exit_error(OTHER_PROBLEM, "out of memory"); + FILE *opts_file = NULL; + char **argv_buf = NULL, *getline_buf = NULL; + size_t argv_buf_size = 0, getline_buf_size = 0; register_tcp(); register_udp(); @@ -2348,6 +2397,23 @@ int main(int argc, char *argv[]) /* disable explicit missing arguments error output from getopt_long */ opterr = 0; +parse_opts: + + options = 0; + filter_family = 0; + memset(dir2network, 0, sizeof(dir2network)); + /* all allocate-able objects get freed zero-inited + * at the end of each iteration */ + + l4flags = 0; + family = AF_UNSPEC; + socketbuffersize = 0; + protonum = 0; + + /* we release these objects in the exit_error() path. */ + if (!alloc_tmpl_objects()) + exit_error(OTHER_PROBLEM, "out of memory"); + while ((c = getopt_long(argc, argv, getopt_str, opts, NULL)) != -1) { switch(c) { /* commands */ @@ -2585,6 +2651,26 @@ int main(int argc, char *argv[]) "`--dst-nat' with `--any-nat'"); } cmd = bit2cmd(command); + + if (!opts_file && optind == argc - 1 && !strcmp(argv[optind], "-")) { + switch (command) { + case CT_CREATE: + case EXP_CREATE: + case CT_UPDATE: + case CT_DELETE: + case EXP_DELETE: + break; + default: + exit_error(PARAMETER_PROBLEM, "stdin mode not supported " + "for this command!"); + } + if (options) + exit_error(PARAMETER_PROBLEM, "no extra options are expected " + "with stdin read mode!"); + opts_file = stdin; + goto next_opts; + } + res = generic_opt_check(options, NUMBER_OF_OPT, commands_v_options[cmd], optflags, addr_valid_flags, ADDR_VALID_FLAGS_MAX, @@ -2670,8 +2756,8 @@ int main(int argc, char *argv[]) printf("\n"); fflush(stdout); } - nfct_close(cth); + cth = NULL; break; case EXP_LIST: @@ -2681,12 +2767,13 @@ int main(int argc, char *argv[]) nfexp_callback_register(cth, NFCT_T_ALL, dump_exp_cb, NULL); res = nfexp_query(cth, NFCT_Q_DUMP, &family); - nfct_close(cth); if (dump_xml_header_done == 0) { printf("\n"); fflush(stdout); } + nfct_close(cth); + cth = NULL; break; case CT_CREATE: @@ -2702,14 +2789,15 @@ int main(int argc, char *argv[]) nfct_set_attr(tmpl.ct, ATTR_CONNLABELS, xnfct_bitmask_clone(tmpl.label_modify)); - cth = nfct_open(CONNTRACK, 0); - if (!cth) - exit_error(OTHER_PROBLEM, "Can't open handler"); + if (!cth) { + cth = nfct_open(CONNTRACK, 0); + if (!cth) + exit_error(OTHER_PROBLEM, "Can't open handler"); + } res = nfct_query(cth, NFCT_Q_CREATE, tmpl.ct); if (res != -1) counter++; - nfct_close(cth); break; case EXP_CREATE: @@ -2717,18 +2805,21 @@ int main(int argc, char *argv[]) nfexp_set_attr(tmpl.exp, ATTR_EXP_EXPECTED, tmpl.exptuple); nfexp_set_attr(tmpl.exp, ATTR_EXP_MASK, tmpl.mask); - cth = nfct_open(EXPECT, 0); - if (!cth) - exit_error(OTHER_PROBLEM, "Can't open handler"); + if (!cth) { + cth = nfct_open(EXPECT, 0); + if (!cth) + exit_error(OTHER_PROBLEM, "Can't open handler"); + } res = nfexp_query(cth, NFCT_Q_CREATE, tmpl.exp); - nfct_close(cth); break; case CT_UPDATE: - cth = nfct_open(CONNTRACK, 0); + if (!cth) + cth = nfct_open(CONNTRACK, 0); /* internal handler for delete_cb, otherwise we hit EILSEQ */ - ith = nfct_open(CONNTRACK, 0); + if (!ith) + ith = nfct_open(CONNTRACK, 0); if (!cth || !ith) exit_error(OTHER_PROBLEM, "Can't open handler"); @@ -2737,13 +2828,13 @@ int main(int argc, char *argv[]) nfct_callback_register(cth, NFCT_T_ALL, update_cb, tmpl.ct); res = nfct_query(cth, NFCT_Q_DUMP, &family); - nfct_close(ith); - nfct_close(cth); break; case CT_DELETE: - cth = nfct_open(CONNTRACK, 0); - ith = nfct_open(CONNTRACK, 0); + if (!cth) + cth = nfct_open(CONNTRACK, 0); + if (!ith) + ith = nfct_open(CONNTRACK, 0); if (!cth || !ith) exit_error(OTHER_PROBLEM, "Can't open handler"); @@ -2768,19 +2859,18 @@ int main(int argc, char *argv[]) nfct_filter_dump_destroy(filter_dump); - nfct_close(ith); - nfct_close(cth); break; case EXP_DELETE: nfexp_set_attr(tmpl.exp, ATTR_EXP_EXPECTED, tmpl.ct); - cth = nfct_open(EXPECT, 0); - if (!cth) - exit_error(OTHER_PROBLEM, "Can't open handler"); + if (!cth) { + cth = nfct_open(EXPECT, 0); + if (!cth) + exit_error(OTHER_PROBLEM, "Can't open handler"); + } res = nfexp_query(cth, NFCT_Q_DESTROY, tmpl.exp); - nfct_close(cth); break; case CT_GET: @@ -2791,6 +2881,7 @@ int main(int argc, char *argv[]) nfct_callback_register(cth, NFCT_T_ALL, dump_cb, tmpl.ct); res = nfct_query(cth, NFCT_Q_GET, tmpl.ct); nfct_close(cth); + cth = NULL; break; case EXP_GET: @@ -2803,6 +2894,7 @@ int main(int argc, char *argv[]) nfexp_callback_register(cth, NFCT_T_ALL, dump_exp_cb, NULL); res = nfexp_query(cth, NFCT_Q_GET, tmpl.exp); nfct_close(cth); + cth = NULL; break; case CT_FLUSH: @@ -2810,9 +2902,10 @@ int main(int argc, char *argv[]) if (!cth) exit_error(OTHER_PROBLEM, "Can't open handler"); res = nfct_query(cth, NFCT_Q_FLUSH, &family); - nfct_close(cth); fprintf(stderr, "%s v%s (conntrack-tools): ",PROGNAME,VERSION); fprintf(stderr,"connection tracking table has been emptied.\n"); + nfct_close(cth); + cth = NULL; break; case EXP_FLUSH: @@ -2820,9 +2913,10 @@ int main(int argc, char *argv[]) if (!cth) exit_error(OTHER_PROBLEM, "Can't open handler"); res = nfexp_query(cth, NFCT_Q_FLUSH, &family); - nfct_close(cth); fprintf(stderr, "%s v%s (conntrack-tools): ",PROGNAME,VERSION); fprintf(stderr,"expectation table has been emptied.\n"); + nfct_close(cth); + cth = NULL; break; case CT_EVENT: @@ -2894,6 +2988,8 @@ int main(int argc, char *argv[]) res = mnl_cb_run(buf, res, 0, 0, event_cb, tmpl.ct); } mnl_socket_close(sock.mnl); + nfct_close(cth); + cth = NULL; break; case EXP_EVENT: @@ -2922,6 +3018,7 @@ int main(int argc, char *argv[]) nfexp_callback_register(cth, NFCT_T_ALL, event_exp_cb, NULL); res = nfexp_catch(cth); nfct_close(cth); + cth = NULL; break; case CT_COUNT: /* If we fail with netlink, fall back to /proc to ensure @@ -2966,6 +3063,7 @@ try_proc_count: nfexp_callback_register(cth, NFCT_T_ALL, count_exp_cb, NULL); res = nfexp_query(cth, NFCT_Q_DUMP, &family); nfct_close(cth); + cth = NULL; printf("%d\n", counter); break; case CT_STATS: @@ -3024,10 +3122,35 @@ try_proc: exit_error(OTHER_PROBLEM, "Operation failed: %s", err2str(errno, command)); +next_opts: free_tmpl_objects(); free_options(); - if (labelmap) + if (labelmap) { nfct_labelmap_destroy(labelmap); + labelmap = NULL; + } + + if (opts_file) { + while ((res = getline(&getline_buf, &getline_buf_size, opts_file)) >= 0) { + if (!res) + continue; + argc = line_to_argcv(argv[0], getline_buf, &argv_buf, &argv_buf_size); + if (!argc) + continue; + argv = argv_buf; + + cur_argc = argc; + cur_argv = argv; + + optind = 0; + goto parse_opts; + } + } + + if (ith) + nfct_close(ith); + if (cth) + nfct_close(cth); if (command && exit_msg[cmd][0]) { fprintf(stderr, "%s v%s (conntrack-tools): ",PROGNAME,VERSION); @@ -3036,5 +3159,8 @@ try_proc: return EXIT_FAILURE; } + free(argv_buf); + free(getline_buf); + return EXIT_SUCCESS; } From patchwork Fri Sep 25 12:49:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Mikhail Sennikovsky X-Patchwork-Id: 1371259 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=cloud.ionos.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=cloud.ionos.com header.i=@cloud.ionos.com header.a=rsa-sha256 header.s=google header.b=a4VBjnlB; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4ByWvw54zxz9sTg for ; Fri, 25 Sep 2020 22:49:48 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728949AbgIYMtr (ORCPT ); Fri, 25 Sep 2020 08:49:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38354 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728944AbgIYMtq (ORCPT ); Fri, 25 Sep 2020 08:49:46 -0400 Received: from mail-ej1-x644.google.com (mail-ej1-x644.google.com [IPv6:2a00:1450:4864:20::644]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2B546C0613D3 for ; Fri, 25 Sep 2020 05:49:46 -0700 (PDT) Received: by mail-ej1-x644.google.com with SMTP id u21so3495102eja.2 for ; Fri, 25 Sep 2020 05:49:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloud.ionos.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Szcw+U76HIs6iefUa0ynf54phCV37I9aJ1dT8Lwzd5U=; b=a4VBjnlBTU7WVcRcF5weMpLGmJ9DpLZaHrcWgN6dQBph6xJazAiIoimc1HNlGwY7AH cYaxpSZrS7iNhj8DtlvLAgJMcMvC6zaNiQdQMvAJ2DqsmX1WECV8JZkdlppqeVFcL/wo xSz0POc8RVim58bdVZWn3UivFxVKNVDnYKhf03xp82kXjFg3oln1XaegCIeztz0L98KY o8wbgIi7AS7BCgyl1Jg72cozMTwJO1gA11NVhu3iZYadxH+qRerYvOQCxYmy9Utp0Rsm CzaiXNVVW4MERGFig9DJ9aWE9arznu93w+XkswCaU22Xoe3DiXHUS9DTBNR5GtiptgfM SjZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Szcw+U76HIs6iefUa0ynf54phCV37I9aJ1dT8Lwzd5U=; b=CHFZJfts+4ZcRRolr2rWTtGhnLLWNifULGPWgrVj15WmZngtsfLY4czwv2YFqEEaR4 StJSBTf0+l0/0QkhjTGIP8is/WOHkEkqANd95tbCg4XPsjqSyf1jbX69No2myAvoacqZ y8BhRm1XbhcP3qDeoSSLEJ8ngCSw8NVbtocE6FM++ExQ0vaq6uOtAIR6c+C9qPGGzO8z 552oVVAz5CFSru27PBnUYI4P74ImhybDdnEuOOqFtJxDrjC+5ptQPh5FKXZgW0S0HHC9 qAtQSz895+6k8Mz1S71JHBvQAJenvMa+uhxo2yfRkPLZrkLcIE7+PjVqpF3TM4DyNwCC JBMA== X-Gm-Message-State: AOAM532mSMwLlIcRMUL/4aR1O4I0FE4W/w/CCr0bQANIoXZMRqxqBwab K2tV+2YAkn6S9ILhUOfkRfcwPH0UKU1WFQ== X-Google-Smtp-Source: ABdhPJzTqz+51Tr2jFY+0fN3RbcS0WXhiIP5W6VKB4ZfnKvEL60M2z3LN7Y5eHl9SCs36MLvjIpHDg== X-Received: by 2002:a17:906:390d:: with SMTP id f13mr2531612eje.86.1601038184750; Fri, 25 Sep 2020 05:49:44 -0700 (PDT) Received: from localhost.localdomain (dynamic-046-114-037-141.46.114.pool.telefonica.de. [46.114.37.141]) by smtp.gmail.com with ESMTPSA id t3sm1761642edv.59.2020.09.25.05.49.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Sep 2020 05:49:44 -0700 (PDT) From: Mikhail Sennikovsky To: netfilter-devel@vger.kernel.org Cc: Mikhail Sennikovsky Subject: [PATCH 4/8] conntrack.8: man update for stdin params support Date: Fri, 25 Sep 2020 14:49:15 +0200 Message-Id: <20200925124919.9389-5-mikhail.sennikovskii@cloud.ionos.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200925124919.9389-1-mikhail.sennikovskii@cloud.ionos.com> References: <20200925124919.9389-1-mikhail.sennikovskii@cloud.ionos.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Signed-off-by: Mikhail Sennikovsky --- conntrack.8 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/conntrack.8 b/conntrack.8 index 1174c6c..3db4849 100644 --- a/conntrack.8 +++ b/conntrack.8 @@ -135,6 +135,14 @@ to overrun the socket buffer. Note that using a big buffer reduces the chances to hit ENOBUFS, however, this results in more memory consumption. . This option can only be used in conjunction with "\-E, \-\-event". +.TP +.BI "-" +Make conntrack accept multiple sets of ct entry-related parameters on stdin. +This option is useful for the fast bulk conntrack entries updates. +. +This option can only be used in conjunction with "\-I, \-\-create", +"\-U, \-\-update" and "\-D, \-\-delete". +No other options are allowed to be present on the command line. .SS FILTER PARAMETERS .TP From patchwork Fri Sep 25 12:49:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Sennikovsky X-Patchwork-Id: 1371274 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=cloud.ionos.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=cloud.ionos.com header.i=@cloud.ionos.com header.a=rsa-sha256 header.s=google header.b=YOI+Ms8B; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4ByX5X5YJRz9sVW for ; Fri, 25 Sep 2020 22:58:08 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729610AbgIYM6G (ORCPT ); Fri, 25 Sep 2020 08:58:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38360 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728944AbgIYMtr (ORCPT ); Fri, 25 Sep 2020 08:49:47 -0400 Received: from mail-ed1-x533.google.com (mail-ed1-x533.google.com [IPv6:2a00:1450:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 441A3C0613CE for ; Fri, 25 Sep 2020 05:49:47 -0700 (PDT) Received: by mail-ed1-x533.google.com with SMTP id w1so2373337edr.3 for ; Fri, 25 Sep 2020 05:49:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloud.ionos.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yYSZlWPccmhB/zYCiVJbunvrem0oE06lPNleWa7CLtE=; b=YOI+Ms8BWoVDWMojBX6ORusPHLgt1sfGzk29GaWOb2vlkxx0MjNM48CyG3xoz8C8pr or5gI9W88jpRy5bZ3bpAwHbIk+y2datxVm9gkZWAg7DmxD/Yg28/xZzBQZb5wQs7BE7V OCmD5pRNtw0Dmkbsz4MHgQg7o9zh/QshoC6Z+ChmlJHlh8R0dc7fmtjCxGrkcdUYCvGC ihpPUWNUZxmV//xWjXGZvwkG1kQ/VijUmg1eLmxBx5PjRxuwh2AyViT+7QYcrTM7+NbI sQn4UB0ujAF0xX3fKyi7lOi4oUEM5P+V2cGwwk+C/rcqhY2kfDHZSM+VNXmdJvL6y8AF husA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yYSZlWPccmhB/zYCiVJbunvrem0oE06lPNleWa7CLtE=; b=p4Gepo9zsHeO1+yHHIETwNSkX7rOydtQciXOTcz1B2Z3nmzuCm3jUqPrriquWIbaXt U55EBYnP8+3SaC3qdrkKfNQlG2wZBBaURA5Kxqg2S1ooQie8jxNOwr6IVBtT70hWHNdP xeRHT+BLuROAE/aCLss5hNLO0GX/1U9OYXMn9875r1QgXWPPkAXbPN3kRQNkgzWopnUl pjV8WXyOLQ35w3BNwOfKoBMp7jhPFzArFkzaBy/yPkKOJQv+GO+cHhHA+FWbiD5uIWdy 99KGTDuLqAO+vImVwjV+BzBgGvnUHQABk4H4rG6xJ8DDu3DTjAmDHt3J6ZQ0NFVUJ+Ah mxzw== X-Gm-Message-State: AOAM533AbztGhCa/PWZjawNlQwC7khoEW3tU7AYa1awpjA3emtV/b8lD Tle1oAf67fBnqTFgFj1UcNh/dHhkuPJtEw== X-Google-Smtp-Source: ABdhPJyWPj945QwFsm2vnSk+jxf3XUBN6AGKYuqBU2Y/Jh99nihmH7ROrjbG15GP/Y1a5Psz8mAqGQ== X-Received: by 2002:aa7:c419:: with SMTP id j25mr1116828edq.109.1601038185633; Fri, 25 Sep 2020 05:49:45 -0700 (PDT) Received: from localhost.localdomain (dynamic-046-114-037-141.46.114.pool.telefonica.de. [46.114.37.141]) by smtp.gmail.com with ESMTPSA id t3sm1761642edv.59.2020.09.25.05.49.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Sep 2020 05:49:45 -0700 (PDT) From: Mikhail Sennikovsky To: netfilter-devel@vger.kernel.org Cc: Mikhail Sennikovsky Subject: [PATCH 5/8] tests: conntrack parameters from stdin Date: Fri, 25 Sep 2020 14:49:16 +0200 Message-Id: <20200925124919.9389-6-mikhail.sennikovskii@cloud.ionos.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200925124919.9389-1-mikhail.sennikovskii@cloud.ionos.com> References: <20200925124919.9389-1-mikhail.sennikovskii@cloud.ionos.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Add tests to cover handling parameters from stdin by conntrack Signed-off-by: Mikhail Sennikovsky --- tests/conntrack/test-conntrack.c | 70 +++++++++++++++++++++++++------ tests/conntrack/testsuite/08stdin | 62 +++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 12 deletions(-) create mode 100644 tests/conntrack/testsuite/08stdin diff --git a/tests/conntrack/test-conntrack.c b/tests/conntrack/test-conntrack.c index 76ab051..90bdc5b 100644 --- a/tests/conntrack/test-conntrack.c +++ b/tests/conntrack/test-conntrack.c @@ -28,6 +28,23 @@ int main() struct dirent *dent; char file[1024]; int i,n; + char cmd_buf[1024 * 8]; + int i_cmd_buf = 0; + char cmd, cur_cmd = 0; + char *cmd_opt; + +#define cmd_strappend(_s) do { \ + char * pos = stpncpy(cmd_buf + i_cmd_buf, _s, sizeof(cmd_buf) - i_cmd_buf); \ + i_cmd_buf = pos - cmd_buf; \ + if (i_cmd_buf == sizeof(cmd_buf)) { \ + printf("buffer full!\n"); \ + exit(EXIT_FAILURE); \ + } \ +} while (0) + +#define cmd_reset() do { \ + i_cmd_buf = 0; \ +} while (0) n = scandir("testsuite", &dents, NULL, alphasort); @@ -48,9 +65,7 @@ int main() } while (fgets(buf, sizeof(buf), fp)) { - char tmp[1024] = CT_PROG, *res; - tmp[strlen(CT_PROG)] = ' '; - + char *res; line++; if (buf[0] == '#' || buf[0] == ' ') @@ -63,27 +78,58 @@ int main() exit(EXIT_FAILURE); } *res = '\0'; - res+=2; + res++; + for (; *res == ' ' || *res == '\t'; res++); + cmd = res[0]; + + if (cur_cmd && cmd != cur_cmd) { + /* complete current multi-line command */ + switch (cur_cmd) { + case '\n': + cmd_strappend("\" | "); + break; + default: + printf("Internal Error: unexpected multiline command %c", + cur_cmd); + exit(EXIT_FAILURE); + break; + } + + cur_cmd = 0; + } + + switch (cmd) { + case '\n': + if (!cur_cmd) { + cmd_strappend("echo \""); + cur_cmd = cmd; + } else + cmd_strappend("\n"); + cmd_strappend(buf); + continue; + default: + cmd_strappend(CT_PROG); + cmd_strappend(" "); + cmd_strappend(buf); + cmd_reset(); + break; + } - strcpy(tmp + strlen(CT_PROG) + 1, buf); - printf("(%d) Executing: %s\n", line, tmp); + printf("(%d) Executing: %s\n", line, cmd_buf); fflush(stdout); - ret = system(tmp); + ret = system(cmd_buf); if (WIFEXITED(ret) && WEXITSTATUS(ret) == EXIT_SUCCESS) { - if (res[0] == 'O' && - res[1] == 'K') + if (cmd == 'O') ok++; else { bad++; printf("^----- BAD\n"); } } else { - if (res[0] == 'B' && - res[1] == 'A' && - res[2] == 'D') + if (cmd == 'B') ok++; else { bad++; diff --git a/tests/conntrack/testsuite/08stdin b/tests/conntrack/testsuite/08stdin new file mode 100644 index 0000000..cf3eadd --- /dev/null +++ b/tests/conntrack/testsuite/08stdin @@ -0,0 +1,62 @@ +# create +# create a conntrack +-s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +# create from reply +-r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; +# create a v6 conntrack +-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +# creae icmp ping request entry +-t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; +-I - ; OK +# create again +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD +# make sure create again with stdio mode fails as well +-s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +-I - ; BAD +-r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; +-I - ; BAD +# empty lines are ignored +; +-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +-I - ; BAD +# spaces or tabs are ignored as well + ; + ; +-t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; +-I - ; BAD +# delete +-s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; +# empty lines should be just ignored +; +; +# delete reverse +-r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; +# empty lines with spaces or tabs should be ignored as well + ; + ; + ; + ; + ; + ; +# delete v6 conntrack +-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; +# delete icmp ping request entry +-u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; +; +; +-D - ; OK +# create again - should succeed now +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK +-I -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; OK +-I -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK +-I -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK +# delete again (for cleanup) +-s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; +-r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; +-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; +-u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; +; +-D - ; OK From patchwork Fri Sep 25 12:49:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Sennikovsky X-Patchwork-Id: 1371273 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=cloud.ionos.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=cloud.ionos.com header.i=@cloud.ionos.com header.a=rsa-sha256 header.s=google header.b=JgEg+Ay2; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4ByX5W3zGWz9sVD for ; Fri, 25 Sep 2020 22:58:07 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729425AbgIYM6G (ORCPT ); Fri, 25 Sep 2020 08:58:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38368 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728954AbgIYMtt (ORCPT ); Fri, 25 Sep 2020 08:49:49 -0400 Received: from mail-ej1-x643.google.com (mail-ej1-x643.google.com [IPv6:2a00:1450:4864:20::643]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C83AAC0613CE for ; Fri, 25 Sep 2020 05:49:48 -0700 (PDT) Received: by mail-ej1-x643.google.com with SMTP id p15so2874864ejm.7 for ; Fri, 25 Sep 2020 05:49:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloud.ionos.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=E0dmc2pklOk2HMRRZNWan9GmdWl+0xRqwT7hZ0ltRCQ=; b=JgEg+Ay2uKxUv1ENfsqruSveoWActElUwhud4U0SaTJN3FwhsVwPOkMZMJwm+W+JwY aOQmP+W0Y/tnr3z9oRlc20LCc6GESEDQRU+kCumyIIHNd2dR7YIk3xZ+3GzK201nwkbU /iLulTOiBo/JnYTdDxHLXUgJnc2ortKWMdI2znzEfG+OlzyR/81D/TqcaPZc0HaJQQBu CcqTwFnZZcPudHjHBfkDsIsK/VReyLbPsWaq1TBpVppOYjq+EGgG4DotLeX3uGhoJjYQ RubTjpEdskVERBDziKC2GO8gJBa35By0SCXTOwpzkplbXaWm9iBJhc1rafL31Jz5QAKi GmKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=E0dmc2pklOk2HMRRZNWan9GmdWl+0xRqwT7hZ0ltRCQ=; b=oIFhOnX6t2d1uV0aeEoChP7jDtgXXd5/8Lfqt4RFjyad32pXxYKunEV8MHIc8WcelL sDAMuvc19ZBhdseW7HpY95ZRmXNElYApdCAo4cYDwkWCgxDn01nhP3lbonn467VnDAhH PoDVv5UhAgxXbLwDbt37th0+x6avtJqtYEx/54iC3aVpQFCqZ3WWjl8XTVK6CRcDv2Oi 4DGGzallMc6EtUnXjJ3YkJ0GH/GokF0pCwlRmrqC0IOaYd5RFoYNYJQAGUjpvD/9Hcmx tHEMNxiAd/3cPLF5dYUy73omABoJmyJhFMGKBQpM04l0BX5uTR0iRbyExVZrGaFfx5H4 G9GA== X-Gm-Message-State: AOAM5310JYmDsnEWYi+4p5R6M75u5Jm9LCSU9LPopHYAqYJUlU7qMKXE X6ZYiBglfn6s1R5IOIN+H0uKVsCTnzrwqA== X-Google-Smtp-Source: ABdhPJxjVGaMlJn2bM/e2AbqhYA4DYIqos3Kw1/GsPjvuteC3EJReh8fcg7X6Q+NAQuMUafPvfvQBQ== X-Received: by 2002:a17:906:bcfc:: with SMTP id op28mr2621038ejb.248.1601038186750; Fri, 25 Sep 2020 05:49:46 -0700 (PDT) Received: from localhost.localdomain (dynamic-046-114-037-141.46.114.pool.telefonica.de. [46.114.37.141]) by smtp.gmail.com with ESMTPSA id t3sm1761642edv.59.2020.09.25.05.49.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Sep 2020 05:49:46 -0700 (PDT) From: Mikhail Sennikovsky To: netfilter-devel@vger.kernel.org Cc: Mikhail Sennikovsky Subject: [PATCH 6/8] conntrack: implement options output format Date: Fri, 25 Sep 2020 14:49:17 +0200 Message-Id: <20200925124919.9389-7-mikhail.sennikovskii@cloud.ionos.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200925124919.9389-1-mikhail.sennikovskii@cloud.ionos.com> References: <20200925124919.9389-1-mikhail.sennikovskii@cloud.ionos.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org As a counterpart to the "conntrack: accept parameters from stdin" commit, this commit allows dumping conntrack entries in the format used by the conntrack parameters. This is useful for transfering a large set of ct entries between hosts or between different ct zones in an efficient way. To enable the "options" output the "-o opts" parameter needs to be passed to the "contnrack -L" tool invocation. To demonstrate the overall idea of the options output format works in conjunction with the "stdin parameter"s mode, the following command will copy all ct entries from one ct zone to another. conntrack -L -w 15 -o opts | sed 's/-w 15/-w 9915/g' | conntrack -I - Signed-off-by: Mikhail Sennikovsky --- extensions/libct_proto_dccp.c | 24 +++ extensions/libct_proto_gre.c | 16 ++ extensions/libct_proto_icmp.c | 15 ++ extensions/libct_proto_icmpv6.c | 15 ++ extensions/libct_proto_sctp.c | 19 +++ extensions/libct_proto_tcp.c | 17 ++ extensions/libct_proto_udp.c | 16 ++ extensions/libct_proto_udplite.c | 16 ++ include/conntrack.h | 38 +++++ src/conntrack.c | 261 ++++++++++++++++++++++++++++++- 10 files changed, 433 insertions(+), 4 deletions(-) diff --git a/extensions/libct_proto_dccp.c b/extensions/libct_proto_dccp.c index f6258ad..cfe1313 100644 --- a/extensions/libct_proto_dccp.c +++ b/extensions/libct_proto_dccp.c @@ -198,6 +198,29 @@ static int parse_options(char c, return 1; } + +static const char *dccp_roles[__DCCP_CONNTRACK_ROLE_MAX] = { + [DCCP_CONNTRACK_ROLE_CLIENT] = "client", + [DCCP_CONNTRACK_ROLE_SERVER] = "server", +}; + +static struct ctproto_attr attrs[] = { + {"--sport", ATTR_ORIG_PORT_SRC, CTPROTO_ATTR_U16_N, 0, 0}, + {"--dport", ATTR_ORIG_PORT_DST, CTPROTO_ATTR_U16_N, 0, 0}, + {"--reply-port-src", ATTR_REPL_PORT_SRC, CTPROTO_ATTR_U16_N, 0, 0}, + {"--reply-port-dst", ATTR_REPL_PORT_DST, CTPROTO_ATTR_U16_N, 0, 0}, + {"--state", ATTR_DCCP_STATE, CTPROTO_ATTR_U8, DCCP_CONNTRACK_MAX, dccp_states}, + {"--role", ATTR_DCCP_ROLE, CTPROTO_ATTR_U8, __DCCP_CONNTRACK_ROLE_MAX, dccp_roles}, + {0, 0, 0, 0, 0}, +}; + +static int snprintf_options(char *buf, + unsigned int len, + const struct nf_conntrack *ct) +{ + return snprintf_attrs(buf, len, ct, attrs); +} + #define DCCP_VALID_FLAGS_MAX 2 static unsigned int dccp_valid_flags[DCCP_VALID_FLAGS_MAX] = { CT_DCCP_ORIG_SPORT | CT_DCCP_ORIG_DPORT, @@ -235,6 +258,7 @@ static struct ctproto_handler dccp = { .protonum = IPPROTO_DCCP, .parse_opts = parse_options, .final_check = final_check, + .snprintf_options = snprintf_options, .help = help, .opts = opts, .version = VERSION, diff --git a/extensions/libct_proto_gre.c b/extensions/libct_proto_gre.c index 2dc63d1..b03887b 100644 --- a/extensions/libct_proto_gre.c +++ b/extensions/libct_proto_gre.c @@ -144,6 +144,21 @@ static int parse_options(char c, return 1; } +static struct ctproto_attr attrs[] = { + {"--srckey", ATTR_ORIG_PORT_SRC, CTPROTO_ATTR_U16_N, 0, 0}, + {"--dstkey", ATTR_ORIG_PORT_DST, CTPROTO_ATTR_U16_N, 0, 0}, + {"--reply-key-src", ATTR_REPL_PORT_SRC, CTPROTO_ATTR_U16_N, 0, 0}, + {"--reply-key-dst", ATTR_REPL_PORT_DST, CTPROTO_ATTR_U16_N, 0, 0}, + {0, 0, 0, 0, 0}, +}; + +static int snprintf_options(char *buf, + unsigned int len, + const struct nf_conntrack *ct) +{ + return snprintf_attrs(buf, len, ct, attrs); +} + #define GRE_VALID_FLAGS_MAX 2 static unsigned int gre_valid_flags[GRE_VALID_FLAGS_MAX] = { CT_GRE_ORIG_SKEY | CT_GRE_ORIG_DKEY, @@ -181,6 +196,7 @@ static struct ctproto_handler gre = { .protonum = IPPROTO_GRE, .parse_opts = parse_options, .final_check = final_check, + .snprintf_options = snprintf_options, .help = help, .opts = opts, .version = VERSION, diff --git a/extensions/libct_proto_icmp.c b/extensions/libct_proto_icmp.c index 16c2e2e..e1af53f 100644 --- a/extensions/libct_proto_icmp.c +++ b/extensions/libct_proto_icmp.c @@ -114,6 +114,20 @@ static int parse(char c, return 1; } +static struct ctproto_attr attrs[] = { + {"--icmp-type", ATTR_ICMP_TYPE, CTPROTO_ATTR_U8, 0, 0}, + {"--icmp-code", ATTR_ICMP_CODE, CTPROTO_ATTR_U8, 0, 0}, + {"--icmp-id", ATTR_ICMP_ID, CTPROTO_ATTR_U16_N, 0, 0}, + {0, 0, 0, 0, 0}, +}; + +static int snprintf_options(char *buf, + unsigned int len, + const struct nf_conntrack *ct) +{ + return snprintf_attrs(buf, len, ct, attrs); +} + static void final_check(unsigned int flags, unsigned int cmd, struct nf_conntrack *ct) @@ -129,6 +143,7 @@ static struct ctproto_handler icmp = { .protonum = IPPROTO_ICMP, .parse_opts = parse, .final_check = final_check, + .snprintf_options = snprintf_options, .help = help, .opts = opts, .version = VERSION, diff --git a/extensions/libct_proto_icmpv6.c b/extensions/libct_proto_icmpv6.c index 7f5e637..cb2178e 100644 --- a/extensions/libct_proto_icmpv6.c +++ b/extensions/libct_proto_icmpv6.c @@ -117,6 +117,20 @@ static int parse(char c, return 1; } +static struct ctproto_attr attrs[] = { + {"--icmpv6-type", ATTR_ICMP_TYPE, CTPROTO_ATTR_U8, 0, 0}, + {"--icmpv6-code", ATTR_ICMP_CODE, CTPROTO_ATTR_U8, 0, 0}, + {"--icmpv6-id", ATTR_ICMP_ID, CTPROTO_ATTR_U16_N, 0, 0}, + {0, 0, 0, 0, 0}, +}; + +static int snprintf_options(char *buf, + unsigned int len, + const struct nf_conntrack *ct) +{ + return snprintf_attrs(buf, len, ct, attrs); +} + static void final_check(unsigned int flags, unsigned int cmd, struct nf_conntrack *ct) @@ -131,6 +145,7 @@ static struct ctproto_handler icmpv6 = { .protonum = IPPROTO_ICMPV6, .parse_opts = parse, .final_check = final_check, + .snprintf_options = snprintf_options, .help = help, .opts = opts, .version = VERSION, diff --git a/extensions/libct_proto_sctp.c b/extensions/libct_proto_sctp.c index 04828bf..5b7a43b 100644 --- a/extensions/libct_proto_sctp.c +++ b/extensions/libct_proto_sctp.c @@ -198,6 +198,24 @@ parse_options(char c, struct nf_conntrack *ct, return 1; } +static struct ctproto_attr attrs[] = { + {"--sport", ATTR_ORIG_PORT_SRC, CTPROTO_ATTR_U16_N, 0, 0}, + {"--dport", ATTR_ORIG_PORT_DST, CTPROTO_ATTR_U16_N, 0, 0}, + {"--reply-port-src", ATTR_REPL_PORT_SRC, CTPROTO_ATTR_U16_N, 0, 0}, + {"--reply-port-dst", ATTR_REPL_PORT_DST, CTPROTO_ATTR_U16_N, 0, 0}, + {"--state", ATTR_SCTP_STATE, CTPROTO_ATTR_U8, SCTP_CONNTRACK_MAX, sctp_states}, + {"--orig-vtag", ATTR_SCTP_VTAG_ORIG, CTPROTO_ATTR_U32_N, 0, 0}, + {"--reply-vtag", ATTR_SCTP_VTAG_REPL, CTPROTO_ATTR_U32_N, 0, 0}, + {0, 0, 0, 0, 0}, +}; + +static int snprintf_options(char *buf, + unsigned int len, + const struct nf_conntrack *ct) +{ + return snprintf_attrs(buf, len, ct, attrs); +} + #define SCTP_VALID_FLAGS_MAX 2 static unsigned int dccp_valid_flags[SCTP_VALID_FLAGS_MAX] = { CT_SCTP_ORIG_SPORT | CT_SCTP_ORIG_DPORT, @@ -235,6 +253,7 @@ static struct ctproto_handler sctp = { .protonum = IPPROTO_SCTP, .parse_opts = parse_options, .final_check = final_check, + .snprintf_options = snprintf_options, .help = help, .opts = opts, .version = VERSION, diff --git a/extensions/libct_proto_tcp.c b/extensions/libct_proto_tcp.c index 8a37a55..90fecf6 100644 --- a/extensions/libct_proto_tcp.c +++ b/extensions/libct_proto_tcp.c @@ -177,6 +177,22 @@ static int parse_options(char c, return 1; } +static struct ctproto_attr attrs[] = { + {"--sport", ATTR_ORIG_PORT_SRC, CTPROTO_ATTR_U16_N, 0, 0}, + {"--dport", ATTR_ORIG_PORT_DST, CTPROTO_ATTR_U16_N, 0, 0}, + {"--reply-port-src", ATTR_REPL_PORT_SRC, CTPROTO_ATTR_U16_N, 0, 0}, + {"--reply-port-dst", ATTR_REPL_PORT_DST, CTPROTO_ATTR_U16_N, 0, 0}, + {"--state", ATTR_TCP_STATE, CTPROTO_ATTR_U8, TCP_CONNTRACK_MAX, tcp_states}, + {0, 0, 0, 0, 0}, +}; + +static int snprintf_options(char *buf, + unsigned int len, + const struct nf_conntrack *ct) +{ + return snprintf_attrs(buf, len, ct, attrs); +} + #define TCP_VALID_FLAGS_MAX 2 static unsigned int tcp_valid_flags[TCP_VALID_FLAGS_MAX] = { CT_TCP_ORIG_SPORT | CT_TCP_ORIG_DPORT, @@ -228,6 +244,7 @@ static struct ctproto_handler tcp = { .protonum = IPPROTO_TCP, .parse_opts = parse_options, .final_check = final_check, + .snprintf_options = snprintf_options, .help = help, .opts = opts, .version = VERSION, diff --git a/extensions/libct_proto_udp.c b/extensions/libct_proto_udp.c index e30637c..a70cee0 100644 --- a/extensions/libct_proto_udp.c +++ b/extensions/libct_proto_udp.c @@ -144,6 +144,21 @@ static int parse_options(char c, return 1; } +static struct ctproto_attr attrs[] = { + {"--sport", ATTR_ORIG_PORT_SRC, CTPROTO_ATTR_U16_N, 0, 0}, + {"--dport", ATTR_ORIG_PORT_DST, CTPROTO_ATTR_U16_N, 0, 0}, + {"--reply-port-src", ATTR_REPL_PORT_SRC, CTPROTO_ATTR_U16_N, 0, 0}, + {"--reply-port-dst", ATTR_REPL_PORT_DST, CTPROTO_ATTR_U16_N, 0, 0}, + {0, 0, 0, 0, 0}, +}; + +static int snprintf_options(char *buf, + unsigned int len, + const struct nf_conntrack *ct) +{ + return snprintf_attrs(buf, len, ct, attrs); +} + #define UDP_VALID_FLAGS_MAX 2 static unsigned int udp_valid_flags[UDP_VALID_FLAGS_MAX] = { CT_UDP_ORIG_SPORT | CT_UDP_ORIG_DPORT, @@ -181,6 +196,7 @@ static struct ctproto_handler udp = { .protonum = IPPROTO_UDP, .parse_opts = parse_options, .final_check = final_check, + .snprintf_options = snprintf_options, .help = help, .opts = opts, .version = VERSION, diff --git a/extensions/libct_proto_udplite.c b/extensions/libct_proto_udplite.c index f46cef0..382d990 100644 --- a/extensions/libct_proto_udplite.c +++ b/extensions/libct_proto_udplite.c @@ -148,6 +148,21 @@ static int parse_options(char c, return 1; } +static struct ctproto_attr attrs[] = { + {"--sport", ATTR_ORIG_PORT_SRC, CTPROTO_ATTR_U16_N, 0, 0}, + {"--dport", ATTR_ORIG_PORT_DST, CTPROTO_ATTR_U16_N, 0, 0}, + {"--reply-port-src", ATTR_REPL_PORT_SRC, CTPROTO_ATTR_U16_N, 0, 0}, + {"--reply-port-dst", ATTR_REPL_PORT_DST, CTPROTO_ATTR_U16_N, 0, 0}, + {0, 0, 0, 0, 0}, +}; + +static int snprintf_options(char *buf, + unsigned int len, + const struct nf_conntrack *ct) +{ + return snprintf_attrs(buf, len, ct, attrs); +} + #define UDPLITE_VALID_FLAGS_MAX 2 static unsigned int udplite_valid_flags[UDPLITE_VALID_FLAGS_MAX] = { CT_UDPLITE_ORIG_SPORT | CT_UDPLITE_ORIG_DPORT, @@ -186,6 +201,7 @@ static struct ctproto_handler udplite = { .protonum = IPPROTO_UDPLITE, .parse_opts = parse_options, .final_check = final_check, + .snprintf_options = snprintf_options, .help = help, .opts = opts, .version = VERSION, diff --git a/include/conntrack.h b/include/conntrack.h index 37ccf6e..b518096 100644 --- a/include/conntrack.h +++ b/include/conntrack.h @@ -8,6 +8,9 @@ #include +#include +#include + #define NUMBER_OF_CMD 19 #define NUMBER_OF_OPT 29 @@ -32,6 +35,10 @@ struct ctproto_handler { unsigned int command, struct nf_conntrack *ct); + int (*snprintf_options)(char *buf, + unsigned int len, + const struct nf_conntrack *ct); + void (*help)(void); struct option *opts; @@ -53,6 +60,37 @@ void exit_error(enum exittype status, const char *msg, ...); extern void register_proto(struct ctproto_handler *h); +enum ctproto_attr_value_type { + CTPROTO_ATTR_U8 = 1, + CTPROTO_ATTR_U16_N, + CTPROTO_ATTR_U16_H, + CTPROTO_ATTR_U32_N, + CTPROTO_ATTR_U32_H, + CTPROTO_ATTR_U64_H, + CTPROTO_ATTR_U32_BITMAP, + CTPROTO_ATTR_IPV4, + CTPROTO_ATTR_IPV6, +}; + +struct ctproto_attr { + const char *name; + enum nf_conntrack_attr type; + short value_type; + short val_mapping_count; + const char **val_mapping; +}; + +extern int snprintf_attr(char *buf, + unsigned int len, + const struct nf_conntrack *ct, + const struct ctproto_attr *attr); + +extern int snprintf_attrs(char *buf, + unsigned int len, + const struct nf_conntrack *ct, + const struct ctproto_attr *attrs); + + extern void register_tcp(void); extern void register_udp(void); extern void register_udplite(void); diff --git a/src/conntrack.c b/src/conntrack.c index 5834f2d..a11958b 100644 --- a/src/conntrack.c +++ b/src/conntrack.c @@ -53,6 +53,7 @@ #include #include #include +#include #ifdef HAVE_ARPA_INET_H #include #endif @@ -610,6 +611,222 @@ void register_proto(struct ctproto_handler *h) list_add(&h->head, &proto_list); } +#define BUFFER_SIZE(ret, size, len, offset) do {\ + size += ret; \ + if ((int)ret > (int)len) \ + ret = len; \ + offset += ret; \ + len -= ret; \ +} while(0) + +int snprintf_attr(char *buf, + unsigned int len, + const struct nf_conntrack *ct, + const struct ctproto_attr *attr + ) +{ + uint16_t u16; + uint32_t u32; + uint64_t u64_val = 0; + char ipstr[INET6_ADDRSTRLEN]; + + if (!nfct_attr_is_set(ct, attr->type)) + return 0; + + switch (attr->value_type) { + case CTPROTO_ATTR_U8: + u64_val = nfct_get_attr_u8(ct, attr->type); + break; + case CTPROTO_ATTR_U16_N: + u16 = nfct_get_attr_u16(ct, attr->type); + u64_val = ntohs(u16); + break; + case CTPROTO_ATTR_U16_H: + u64_val = nfct_get_attr_u16(ct, attr->type); + break; + case CTPROTO_ATTR_U32_N: + u32 = nfct_get_attr_u32(ct, attr->type); + u64_val = ntohl(u32); + break; + case CTPROTO_ATTR_U32_H: + u64_val = nfct_get_attr_u32(ct, attr->type); + break; + case CTPROTO_ATTR_U64_H: + u64_val = nfct_get_attr_u64(ct, attr->type); + break; + case CTPROTO_ATTR_IPV4: + inet_ntop(AF_INET, nfct_get_attr(ct, attr->type), ipstr, sizeof(ipstr)); + break; + case CTPROTO_ATTR_IPV6: + inet_ntop(AF_INET6, nfct_get_attr(ct, attr->type), ipstr, sizeof(ipstr)); + break; + case CTPROTO_ATTR_U32_BITMAP: + u64_val = nfct_get_attr_u32(ct, attr->type); + break; + default: + fprintf(stderr, "unsupported type %u\n", attr->value_type); + return 0; + } + + if (attr->value_type == CTPROTO_ATTR_IPV4 + || attr->value_type == CTPROTO_ATTR_IPV6) { + return snprintf(buf, len, "%s %s ", attr->name, ipstr); + } + + if (attr->val_mapping) { + if (attr->value_type == CTPROTO_ATTR_U32_BITMAP) { + unsigned int size = 0, offset = 0, ret, i, imax, found = 0; + + if (!u64_val) + return 0; + + imax = 31 < attr->val_mapping_count ? 31 : attr->val_mapping_count; + for (i = 0; i < imax; ++i) { + if (!(u64_val & (1 << i))) + continue; + if (!attr->val_mapping[i]) + continue; + + if (!found) { + ret = snprintf(buf + offset, len, "%s %s", attr->name, attr->val_mapping[i]); + found = 1; + } else + ret = snprintf(buf + offset, len, ",%s", attr->val_mapping[i]); + BUFFER_SIZE(ret, size, len, offset); + } + + if (found) { + ret = snprintf(buf + offset, len, " "); + BUFFER_SIZE(ret, size, len, offset); + } + return size; + } + + if (u64_val >= (uint64_t)attr->val_mapping_count) { + fprintf(stderr, "too big value for mapping %s %" PRIu64 "\n", + attr->name, u64_val); + return 0; + } + if (!attr->val_mapping[u64_val]) { + fprintf(stderr, "no mapping for %s %" PRIu64 "\n", + attr->name, u64_val); + return 0; + } + return snprintf(buf, len, "%s %s ", attr->name, attr->val_mapping[u64_val]); + } + + return snprintf(buf, len, "%s %" PRIu64 " ", attr->name, u64_val); +} + +int snprintf_attrs(char *buf, + unsigned int len, + const struct nf_conntrack *ct, + const struct ctproto_attr *attrs) +{ + int i; + unsigned int size = 0, offset = 0, ret; + + for (i = 0; attrs[i].name; ++i) { + ret = snprintf_attr(buf + offset, len, ct, &attrs[i]); + BUFFER_SIZE(ret, size, len, offset); + } + + return size; +} + +static struct ctproto_attr attrs_ipv4[] = { + {"-s", ATTR_ORIG_IPV4_SRC, CTPROTO_ATTR_IPV4, 0, 0}, + {"-d", ATTR_ORIG_IPV4_DST, CTPROTO_ATTR_IPV4, 0, 0}, + {"-g", ATTR_DNAT_IPV4, CTPROTO_ATTR_IPV4, 0, 0}, + {"-n", ATTR_SNAT_IPV4, CTPROTO_ATTR_IPV4, 0, 0}, + {"-r", ATTR_REPL_IPV4_SRC, CTPROTO_ATTR_IPV4, 0, 0}, + {"-q", ATTR_REPL_IPV4_DST, CTPROTO_ATTR_IPV4, 0, 0}, + {0, 0, 0, 0, 0}, +}; + +static struct ctproto_attr attrs_ipv6[] = { + {"-s", ATTR_ORIG_IPV6_SRC, CTPROTO_ATTR_IPV6, 0, 0}, + {"-d", ATTR_ORIG_IPV6_DST, CTPROTO_ATTR_IPV6, 0, 0}, + {"-g", ATTR_DNAT_IPV6, CTPROTO_ATTR_IPV6, 0, 0}, + {"-n", ATTR_SNAT_IPV6, CTPROTO_ATTR_IPV6, 0, 0}, + {"-r", ATTR_REPL_IPV6_SRC, CTPROTO_ATTR_IPV6, 0, 0}, + {"-q", ATTR_REPL_IPV6_DST, CTPROTO_ATTR_IPV6, 0, 0}, + {0, 0, 0, 0, 0}, +}; + +static const char *conntrack_status_map[] = { + [IPS_ASSURED_BIT] = "ASSURED", + [IPS_SEEN_REPLY_BIT] = "SEEN_REPLY", + [IPS_FIXED_TIMEOUT_BIT] = "FIXED_TIMEOUT", + [IPS_EXPECTED_BIT] = "EXPECTED" +}; + +static struct ctproto_attr attrs_generic[] = { + {"-t", ATTR_TIMEOUT, CTPROTO_ATTR_U32_H, 0, 0}, + {"-u", ATTR_STATUS, CTPROTO_ATTR_U32_BITMAP, + sizeof(conntrack_status_map)/sizeof(conntrack_status_map[0]), + conntrack_status_map}, + {"-c", ATTR_SECMARK, CTPROTO_ATTR_U32_H, 0, 0}, +/* {"-i", ATTR_ID, CTPROTO_ATTR_U32_H, 0, 0}, */ + {"-w", ATTR_ZONE, CTPROTO_ATTR_U16_H, 0, 0}, + {"--orig-zone", ATTR_ORIG_ZONE, CTPROTO_ATTR_U16_H, 0, 0}, + {"--reply-zone", ATTR_REPL_ZONE, CTPROTO_ATTR_U16_H, 0, 0}, + {0, 0, 0, 0, 0}, +}; + +static int nfct_snprintf_labels_opts(char *buf, + unsigned int len, + const struct nf_conntrack *ct, + struct nfct_labelmap *map) +{ + int ret = 0; + unsigned int size = 0, offset = 0; + uint8_t l3proto, l4proto; + static struct ctproto_attr *attrs_l3; + struct ctproto_handler *cur; + + ret = snprintf_attrs(buf + offset, len, ct, attrs_generic); + BUFFER_SIZE(ret, size, len, offset); + + l3proto = nfct_get_attr_u8(ct, ATTR_ORIG_L3PROTO); + if (!l3proto) + l3proto = nfct_get_attr_u8(ct, ATTR_REPL_L3PROTO); + switch (l3proto) { + case AF_INET: + attrs_l3 = attrs_ipv4; + break; + case AF_INET6: + attrs_l3 = attrs_ipv6; + break; + default: + fprintf(stderr, + "WARNING: unknown l3proto %d, skipping..\n", l3proto); + return 0; + } + + ret = snprintf_attrs(buf + offset, len, ct, attrs_l3); + BUFFER_SIZE(ret, size, len, offset); + + l4proto = nfct_get_attr_u8(ct, ATTR_L4PROTO); + + /* is it in the list of supported protocol? */ + list_for_each_entry(cur, &proto_list, head) { + if (cur->protonum == l4proto) { + ret = snprintf(buf + offset, len, "-p %s ", cur->name); + BUFFER_SIZE(ret, size, len, offset); + ret = cur->snprintf_options(buf + offset, len, ct); + BUFFER_SIZE(ret, size, len, offset); + break; + } + } + + /* skip trailing space, if any */ + for (;size && buf[size-1] == ' '; --size) + buf[size-1] = '\0'; + + return size; +} + extern struct ctproto_handler ct_proto_unknown; static struct ctproto_handler *findproto(char *name, int *pnum) @@ -865,6 +1082,7 @@ enum { _O_KTMS = (1 << 4), _O_CL = (1 << 5), _O_US = (1 << 6), + _O_OPTS = (1 << 7), }; enum { @@ -875,7 +1093,7 @@ enum { }; static struct parse_parameter { - const char *parameter[7]; + const char *parameter[8]; size_t size; unsigned int value[8]; } parse_array[PARSE_MAX] = { @@ -883,8 +1101,8 @@ static struct parse_parameter { { IPS_ASSURED, IPS_SEEN_REPLY, 0, IPS_FIXED_TIMEOUT, IPS_EXPECTED, IPS_OFFLOAD, IPS_HW_OFFLOAD} }, { {"ALL", "NEW", "UPDATES", "DESTROY"}, 4, { CT_EVENT_F_ALL, CT_EVENT_F_NEW, CT_EVENT_F_UPD, CT_EVENT_F_DEL } }, - { {"xml", "extended", "timestamp", "id", "ktimestamp", "labels", "userspace" }, 7, - { _O_XML, _O_EXT, _O_TMS, _O_ID, _O_KTMS, _O_CL, _O_US }, + { {"xml", "extended", "timestamp", "id", "ktimestamp", "labels", "userspace", "opts"}, 8, + { _O_XML, _O_EXT, _O_TMS, _O_ID, _O_KTMS, _O_CL, _O_US, _O_OPTS }, }, }; @@ -1467,6 +1685,11 @@ static int event_cb(const struct nlmsghdr *nlh, void *data) if (nfct_filter(obj, ct)) goto out; + if (output_mask & _O_OPTS) { + nfct_snprintf_labels_opts(buf, sizeof(buf), ct, labelmap); + goto done; + } + if (output_mask & _O_XML) { op_type = NFCT_O_XML; if (dump_xml_header_done) { @@ -1491,7 +1714,7 @@ static int event_cb(const struct nlmsghdr *nlh, void *data) op_flags |= NFCT_OF_ID; nfct_snprintf_labels(buf, sizeof(buf), ct, type, op_type, op_flags, labelmap); - +done: if (output_mask & _O_US) { if (nlh->nlmsg_pid) userspace = true; @@ -1520,6 +1743,11 @@ static int dump_cb(enum nf_conntrack_msg_type type, if (nfct_filter(obj, ct)) return NFCT_CB_CONTINUE; + if (output_mask & _O_OPTS) { + nfct_snprintf_labels_opts(buf, sizeof(buf), ct, labelmap); + goto done; + } + if (output_mask & _O_XML) { op_type = NFCT_O_XML; if (dump_xml_header_done) { @@ -1536,6 +1764,7 @@ static int dump_cb(enum nf_conntrack_msg_type type, op_flags |= NFCT_OF_ID; nfct_snprintf_labels(buf, sizeof(buf), ct, NFCT_T_UNKNOWN, op_type, op_flags, labelmap); +done: printf("%s\n", buf); counter++; @@ -1562,6 +1791,11 @@ static int delete_cb(enum nf_conntrack_msg_type type, "Operation failed: %s", err2str(errno, CT_DELETE)); + if (output_mask & _O_OPTS) { + nfct_snprintf_labels_opts(buf, sizeof(buf), ct, labelmap); + goto done; + } + if (output_mask & _O_XML) op_type = NFCT_O_XML; if (output_mask & _O_EXT) @@ -1570,6 +1804,7 @@ static int delete_cb(enum nf_conntrack_msg_type type, op_flags |= NFCT_OF_ID; nfct_snprintf(buf, sizeof(buf), ct, NFCT_T_UNKNOWN, op_type, op_flags); +done: printf("%s\n", buf); counter++; @@ -1585,6 +1820,11 @@ static int print_cb(enum nf_conntrack_msg_type type, unsigned int op_type = NFCT_O_DEFAULT; unsigned int op_flags = 0; + if (output_mask & _O_OPTS) { + nfct_snprintf_labels_opts(buf, sizeof(buf), ct, labelmap); + goto done; + } + if (output_mask & _O_XML) op_type = NFCT_O_XML; if (output_mask & _O_EXT) @@ -1593,6 +1833,7 @@ static int print_cb(enum nf_conntrack_msg_type type, op_flags |= NFCT_OF_ID; nfct_snprintf_labels(buf, sizeof(buf), ct, NFCT_T_UNKNOWN, op_type, op_flags, labelmap); +done: printf("%s\n", buf); return NFCT_CB_CONTINUE; @@ -1757,6 +1998,12 @@ static int dump_exp_cb(enum nf_conntrack_msg_type type, unsigned int op_type = NFCT_O_DEFAULT; unsigned int op_flags = 0; + if (output_mask & _O_OPTS) { + /* not implemented at the moment */ + exit_error(PARAMETER_PROBLEM, + "opts output format is not supported for table of expectations"); + } + if (output_mask & _O_XML) { op_type = NFCT_O_XML; if (dump_xml_header_done) { @@ -1788,6 +2035,12 @@ static int event_exp_cb(enum nf_conntrack_msg_type type, unsigned int op_type = NFCT_O_DEFAULT; unsigned int op_flags = 0; + if (output_mask & _O_OPTS) { + /* not implemented at the moment */ + exit_error(PARAMETER_PROBLEM, + "opts output format is not supported for table of expectations"); + } + if (output_mask & _O_XML) { op_type = NFCT_O_XML; if (dump_xml_header_done) { From patchwork Fri Sep 25 12:49:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Sennikovsky X-Patchwork-Id: 1371272 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=cloud.ionos.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=cloud.ionos.com header.i=@cloud.ionos.com header.a=rsa-sha256 header.s=google header.b=gHCP6Vh2; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4ByX5V0gq5z9sVD for ; Fri, 25 Sep 2020 22:58:06 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729244AbgIYM6F (ORCPT ); Fri, 25 Sep 2020 08:58:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38370 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728956AbgIYMtt (ORCPT ); Fri, 25 Sep 2020 08:49:49 -0400 Received: from mail-ed1-x542.google.com (mail-ed1-x542.google.com [IPv6:2a00:1450:4864:20::542]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2AAA3C0613D4 for ; Fri, 25 Sep 2020 05:49:49 -0700 (PDT) Received: by mail-ed1-x542.google.com with SMTP id t16so2356842edw.7 for ; Fri, 25 Sep 2020 05:49:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloud.ionos.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=BaP/yAUC/Npei5i+kGiKdvFxDxDOUjpCIz+C+7VvWnU=; b=gHCP6Vh2C4r3zfQa8WfoidB1q9sZZ8qYMaDp7CigmEjhq66PmX0jCxo11ps6CFGCBS 9jB+LT6wqnWaFwT2vSaw4Rt6TmxqxkufopPXmdhAMPuKL87Wz7KTEhBeoofKrB4MXdy5 yiIpk1Yy81ij6v3EdtNVV54D6sWau184i5YigWkbaV3VgyjJ/Sp7zgFJ6/IZkX7A1sZF pR+j1X28IF90PeaFZFdFW0jzG1In+wWmlnaoeyqWFIHYNk2dgcSpGxUfcdFeMwTWSOro IRJSLNxmp1NyA07FvG6FQy6IcINmW9744sAoTx+408FT97yTxc/ipsafI9TnYsJR98fk 9DDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=BaP/yAUC/Npei5i+kGiKdvFxDxDOUjpCIz+C+7VvWnU=; b=UhBzyx0YQuqpYlbMQV5LQbYWzhdH8LlzhPlavUh1aI86AjDzSB9lL59R+whrWo8Kcr QPSEjpZhdDkQAQ9XOl8XqRd5NGyUsHtYkO6ZVvLcSEsU6sfQ344oLa6MJpNJXW3DY7oi CUqxsJ6hhuUkXbfqWUNA4xXBkX+9292VTF7dQ07WL2vuznpap0NGZV65MEIR98u/S/C8 RAoUzCwJ4UEm6dcBWUs3yayLXWgKXAxsoeSYecpyNKcXcLqeOWiTwpNCKoWwZafSvfdH 34k286zqw9NJ1TvsDYRrwYGgftqQ8vofla566lHkFPI7UVeY1X/PLgsSstTUAhkDDoXw j2iA== X-Gm-Message-State: AOAM532/rMrfdsQ9X5Ue4ENPIZpLKwUetVgicuCusSHsIQ37f5/pMcct n/oK/BYPbKDgSoXKh4BBg2T7UhN0bZORVA== X-Google-Smtp-Source: ABdhPJzowvCYnBkMeIpdHIcZa5QCiOXtlQMEVf+MFu76fXnKZWza5ewMdLhhVEOSbxcOidURkqwgpA== X-Received: by 2002:a50:ce06:: with SMTP id y6mr1118939edi.273.1601038187616; Fri, 25 Sep 2020 05:49:47 -0700 (PDT) Received: from localhost.localdomain (dynamic-046-114-037-141.46.114.pool.telefonica.de. [46.114.37.141]) by smtp.gmail.com with ESMTPSA id t3sm1761642edv.59.2020.09.25.05.49.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Sep 2020 05:49:47 -0700 (PDT) From: Mikhail Sennikovsky To: netfilter-devel@vger.kernel.org Cc: Mikhail Sennikovsky Subject: [PATCH 7/8] conntrack.8: man update for opts format support Date: Fri, 25 Sep 2020 14:49:18 +0200 Message-Id: <20200925124919.9389-8-mikhail.sennikovskii@cloud.ionos.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200925124919.9389-1-mikhail.sennikovskii@cloud.ionos.com> References: <20200925124919.9389-1-mikhail.sennikovskii@cloud.ionos.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Signed-off-by: Mikhail Sennikovsky --- conntrack.8 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/conntrack.8 b/conntrack.8 index 3db4849..2d354a7 100644 --- a/conntrack.8 +++ b/conntrack.8 @@ -109,7 +109,7 @@ Show the in-kernel connection tracking system statistics. Atomically zero counters after reading them. This option is only valid in combination with the "\-L, \-\-dump" command options. .TP -.BI "-o, --output [extended,xml,timestamp,id,ktimestamp,labels,userspace] " +.BI "-o, --output [extended,xml,opts,timestamp,id,ktimestamp,labels,userspace] " Display output in a certain format. With the extended output option, this tool displays the layer 3 information. With ktimestamp, it displays the in-kernel timestamp available since 2.6.38 (you can enable it via the \fBsysctl(8)\fP @@ -399,6 +399,9 @@ Delete all flow whose source address is 1.2.3.4 .TP .B conntrack \-U \-s 1.2.3.4 \-m 1 Set connmark to 1 of all the flows whose source address is 1.2.3.4 +.TP +.B conntrack -L -w 15 -o opts | sed 's/-w 15/-w 9915/g' | conntrack -I - +Copy all ct entries from one ct zone 15 to ct zone 9915 .SH BUGS Please, report them to netfilter-devel@vger.kernel.org or file a bug in From patchwork Fri Sep 25 12:49:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Sennikovsky X-Patchwork-Id: 1371260 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=cloud.ionos.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=cloud.ionos.com header.i=@cloud.ionos.com header.a=rsa-sha256 header.s=google header.b=ZbKUuQX7; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4ByWw82MLKz9sTQ for ; Fri, 25 Sep 2020 22:50:00 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728967AbgIYMtw (ORCPT ); Fri, 25 Sep 2020 08:49:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38372 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728959AbgIYMtu (ORCPT ); Fri, 25 Sep 2020 08:49:50 -0400 Received: from mail-ed1-x52c.google.com (mail-ed1-x52c.google.com [IPv6:2a00:1450:4864:20::52c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 180DEC0613CE for ; Fri, 25 Sep 2020 05:49:50 -0700 (PDT) Received: by mail-ed1-x52c.google.com with SMTP id w1so2373494edr.3 for ; Fri, 25 Sep 2020 05:49:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloud.ionos.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=wbmo206wtWTsOQrwwYS0sv3SqIE/iPdanIZPGn0XkAs=; b=ZbKUuQX7ZE1V0GSmbnWIy0t5qHSSVMDDNprD0rX/xWnOWzjqWXXIouoiNnK391FDMv 5A5bKGNj9mesouquK4CD5O9MfuiKZqQXINrHFIpgAS6ltH2gc8XcFdwwDUS/piASj9R+ Ze/85m6ijh8KvbV3CawHLlqVWV8ghH1J4NwNZW9eNVLgPgNeLb5FKpCmTSDZvdtBTPRj FIluH3wtPHZZ8SOipV34Ge5Tsr9ZBEHBiIMqS3OwPh+he92nXgysvmaZjJYtRo5aPbbK Q7FzDUiWhp424A2XEpGCg/gPx7O+F4VNBoiJaHH0jkmM6ZLkesTFj5RC+FkuBqj3oRTG Zwog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=wbmo206wtWTsOQrwwYS0sv3SqIE/iPdanIZPGn0XkAs=; b=SfptopI5JR5vTi2FMUTEcYChUhJTqde9kfK7+2LR2PdWsIXcIi/HN94t1Ph/kyMbA4 FVYEU/NziOLkEm1QYoxtduBR/zhYFpSNh08kVo4pc0tHcuASzL1zUqfu39iFlTCiAIOT 6WbWqP+0owtG2MkIwaBC4Fbs8za573N0WJxNXCfuELcQSaKW+ZrgngJ1FCu7PR78SarL MwLYHVAZf380fLjxloe0n7MJ0FjAKY1RCZDz2Prisx1SVoPYm/Lu4TFLF57iSvPBiWHb Qus4hQe0X3K3dBfTEL5dRHoY1DwM1qcVK3TVSpQFAjGXTpTl+HflhaLy+1y4ydHDGQyX 8awg== X-Gm-Message-State: AOAM533QouFcXQgQaTxZhTT8fVP+eAJRHSjYWQySjZIqPHRGi2Vyj3Cj kAEy/o4WQTXrIMKsHmWrWp9ypQfogvjBIg== X-Google-Smtp-Source: ABdhPJxyESPQGk2Bw114+IfJ9H/cu+9+GAZWsvg5Pd1ZM1mB2fYHz/OtXLwtW5FPLkk+1cF3123ICA== X-Received: by 2002:aa7:d144:: with SMTP id r4mr1097441edo.303.1601038188445; Fri, 25 Sep 2020 05:49:48 -0700 (PDT) Received: from localhost.localdomain (dynamic-046-114-037-141.46.114.pool.telefonica.de. [46.114.37.141]) by smtp.gmail.com with ESMTPSA id t3sm1761642edv.59.2020.09.25.05.49.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Sep 2020 05:49:48 -0700 (PDT) From: Mikhail Sennikovsky To: netfilter-devel@vger.kernel.org Cc: Mikhail Sennikovsky Subject: [PATCH 8/8] tests: dumping ct entries in opts format Date: Fri, 25 Sep 2020 14:49:19 +0200 Message-Id: <20200925124919.9389-9-mikhail.sennikovskii@cloud.ionos.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200925124919.9389-1-mikhail.sennikovskii@cloud.ionos.com> References: <20200925124919.9389-1-mikhail.sennikovskii@cloud.ionos.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Add tests to cover dumping ct entries in "opts" format by conntrack Signed-off-by: Mikhail Sennikovsky --- tests/conntrack/test-conntrack.c | 14 ++++++ tests/conntrack/testsuite/09dumpopt | 77 +++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 tests/conntrack/testsuite/09dumpopt diff --git a/tests/conntrack/test-conntrack.c b/tests/conntrack/test-conntrack.c index 90bdc5b..372e025 100644 --- a/tests/conntrack/test-conntrack.c +++ b/tests/conntrack/test-conntrack.c @@ -81,6 +81,11 @@ int main() res++; for (; *res == ' ' || *res == '\t'; res++); cmd = res[0]; + cmd_opt = &res[1]; + for (; *cmd_opt == ' ' || *cmd_opt == '\t'; cmd_opt++); + res = strchr(cmd_opt, '\n'); + if (res) + *res = '\0'; if (cur_cmd && cmd != cur_cmd) { /* complete current multi-line command */ @@ -111,6 +116,15 @@ int main() cmd_strappend(CT_PROG); cmd_strappend(" "); cmd_strappend(buf); + if (cmd == '|') { + cmd_strappend(" | "); + if (cmd_opt[0]) { + cmd_strappend("sed \""); + cmd_strappend(cmd_opt); + cmd_strappend("\" | "); + } + continue; + } cmd_reset(); break; } diff --git a/tests/conntrack/testsuite/09dumpopt b/tests/conntrack/testsuite/09dumpopt new file mode 100644 index 0000000..0e3c649 --- /dev/null +++ b/tests/conntrack/testsuite/09dumpopt @@ -0,0 +1,77 @@ +# test opts output for -L +# create +# create a conntrack +-w 10 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +# create from reply +-w 10 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; +# create a v6 conntrack +-w 10 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +# creae icmp ping request entry +-w 10 -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; +-I - ; OK +# copy ipv4 bits to zone 11 +-L -w 10 -o opt -f ipv4 ; |s/-w 10/-w 11/g +-I - ; OK +# copy ipv6 bits to zone 11 +-L -w 10 -o opt -f ipv6 ; |s/-w 10/-w 11/g +-I - ; OK +# create again in zone 11 +-I -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -w 11 -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD +# delete new entries +-D -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; OK +# delete reverse +-D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; OK +# delete v6 conntrack +-D -w 11-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK +# delete icmp ping request entry +-D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK +# delete old entries +-D -w 10 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; OK +# delete reverse +-D -w 10 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; OK +# delete v6 conntrack +-D -w 10-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK +# delete icmp ping request entry +-D -w 10 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK +# +# now test opts output for -D +# create entries again +# create a conntrack +-w 10 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +# create from reply +-w 10 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; +# create a v6 conntrack +-w 10 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +# creae icmp ping request entry +-w 10 -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; +-I - ; OK +# move ipv4 bits to zone 11 +-D -w 10 -o opt -f ipv4 ; |s/-w 10/-w 11/g +-I - ; OK +# move ipv6 bits to zone 11 +-D -w 10 -o opt -f ipv6 ; |s/-w 10/-w 11/g +-I - ; OK +# create again in zone 11 +-I -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -w 11 -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD +# delete new entries +-D -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; OK +# delete reverse +-D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; OK +# delete v6 conntrack +-D -w 11-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK +# delete icmp ping request entry +-D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK +# delete old entries +-D -w 10 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; BAD +# delete reverse +-D -w 10 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; BAD +# delete v6 conntrack +-D -w 10-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; BAD +# delete icmp ping request entry +-D -w 10 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD \ No newline at end of file