From owner-svn-src-all@freebsd.org Tue Sep 20 13:23:10 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2B0E9BE10B6; Tue, 20 Sep 2016 13:23:10 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E070DA02; Tue, 20 Sep 2016 13:23:09 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u8KDN9Sf017569; Tue, 20 Sep 2016 13:23:09 GMT (envelope-from ae@FreeBSD.org) Received: (from ae@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u8KDN9Ps017568; Tue, 20 Sep 2016 13:23:09 GMT (envelope-from ae@FreeBSD.org) Message-Id: <201609201323.u8KDN9Ps017568@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ae set sender to ae@FreeBSD.org using -f From: "Andrey V. Elsukov" Date: Tue, 20 Sep 2016 13:23:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r306025 - stable/11/sys/netpfil/ipfw X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Sep 2016 13:23:10 -0000 Author: ae Date: Tue Sep 20 13:23:08 2016 New Revision: 306025 URL: https://svnweb.freebsd.org/changeset/base/306025 Log: MFC r305778: Fix swap tables between sets when this functional is enabled. We have 6 opcode rewriters for table opcodes. When `set swap' command invoked, it is called for each rewriter, so at the end we get the same result, because opcode rewriter uses ETLV type to match opcode. And all tables opcodes have the same ETLV type. To solve this problem, use separate sets handler for one opcode rewriter. Use it to handle TEST_ALL, SWAP_ALL and MOVE_ALL commands. PR: 212630 Modified: stable/11/sys/netpfil/ipfw/ip_fw_table.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/netpfil/ipfw/ip_fw_table.c ============================================================================== --- stable/11/sys/netpfil/ipfw/ip_fw_table.c Tue Sep 20 12:59:30 2016 (r306024) +++ stable/11/sys/netpfil/ipfw/ip_fw_table.c Tue Sep 20 13:23:08 2016 (r306025) @@ -2825,13 +2825,12 @@ table_manage_sets(struct ip_fw_chain *ch switch (cmd) { case SWAP_ALL: case TEST_ALL: + case MOVE_ALL: /* - * Return success for TEST_ALL, since nothing prevents - * move rules from one set to another. All tables are - * accessible from all sets when per-set tables sysctl - * is disabled. + * Always return success, the real action and decision + * should make table_manage_sets_all(). */ - case MOVE_ALL: + return (0); case TEST_ONE: case MOVE_ONE: /* @@ -2856,6 +2855,39 @@ table_manage_sets(struct ip_fw_chain *ch set, new_set, cmd)); } +/* + * We register several opcode rewriters for lookup tables. + * All tables opcodes have the same ETLV type, but different subtype. + * To avoid invoking sets handler several times for XXX_ALL commands, + * we use separate manage_sets handler. O_RECV has the lowest value, + * so it should be called first. + */ +static int +table_manage_sets_all(struct ip_fw_chain *ch, uint16_t set, uint8_t new_set, + enum ipfw_sets_cmd cmd) +{ + + switch (cmd) { + case SWAP_ALL: + case TEST_ALL: + /* + * Return success for TEST_ALL, since nothing prevents + * move rules from one set to another. All tables are + * accessible from all sets when per-set tables sysctl + * is disabled. + */ + case MOVE_ALL: + if (V_fw_tables_sets == 0) + return (0); + break; + default: + return (table_manage_sets(ch, set, new_set, cmd)); + } + /* Use generic sets handler when per-set sysctl is enabled. */ + return (ipfw_obj_manage_sets(CHAIN_TO_NI(ch), IPFW_TLV_TBL_NAME, + set, new_set, cmd)); +} + static struct opcode_obj_rewrite opcodes[] = { { .opcode = O_IP_SRC_LOOKUP, @@ -2905,7 +2937,7 @@ static struct opcode_obj_rewrite opcodes .find_byname = table_findbyname, .find_bykidx = table_findbykidx, .create_object = create_table_compat, - .manage_sets = table_manage_sets, + .manage_sets = table_manage_sets_all, }, { .opcode = O_VIA,