From owner-svn-src-head@freebsd.org Sat Oct 27 07:32:27 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E4DB810DD8F4; Sat, 27 Oct 2018 07:32:26 +0000 (UTC) (envelope-from eugen@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 9B6C382AF8; Sat, 27 Oct 2018 07:32:26 +0000 (UTC) (envelope-from eugen@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 mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 7C97D55D8; Sat, 27 Oct 2018 07:32:26 +0000 (UTC) (envelope-from eugen@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w9R7WQ1J021533; Sat, 27 Oct 2018 07:32:26 GMT (envelope-from eugen@FreeBSD.org) Received: (from eugen@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w9R7WQYu021532; Sat, 27 Oct 2018 07:32:26 GMT (envelope-from eugen@FreeBSD.org) Message-Id: <201810270732.w9R7WQYu021532@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: eugen set sender to eugen@FreeBSD.org using -f From: Eugene Grosbein Date: Sat, 27 Oct 2018 07:32:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r339810 - head/sys/netpfil/ipfw X-SVN-Group: head X-SVN-Commit-Author: eugen X-SVN-Commit-Paths: head/sys/netpfil/ipfw X-SVN-Commit-Revision: 339810 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 27 Oct 2018 07:32:27 -0000 Author: eugen Date: Sat Oct 27 07:32:26 2018 New Revision: 339810 URL: https://svnweb.freebsd.org/changeset/base/339810 Log: ipfw: implement ngtee/netgraph actions for layer-2 frames. Kernel part of ipfw does not support and ignores rules other than "pass", "deny" and dummynet-related for layer-2 (ethernet frames). Others are processed as "pass". Make it support ngtee/netgraph rules just like they are supported for IP packets. For example, this allows us to mirror some frames selectively to another interface for delivery to remote network analyzer over RSPAN vlan. Assuming ng_ipfw(4) netgraph node has a hook named "900" attached to "lower" hook of vlan900's ng_ether(4) node, that would be as simple as: ipfw add ngtee 900 ip from any to 8.8.8.8 layer2 out xmit igb0 PR: 213452 MFC after: 1 month Tested-by: Fyodor Ustinov Modified: head/sys/netpfil/ipfw/ip_fw_pfil.c Modified: head/sys/netpfil/ipfw/ip_fw_pfil.c ============================================================================== --- head/sys/netpfil/ipfw/ip_fw_pfil.c Sat Oct 27 05:26:09 2018 (r339809) +++ head/sys/netpfil/ipfw/ip_fw_pfil.c Sat Oct 27 07:32:26 2018 (r339810) @@ -317,11 +317,12 @@ ipfw_check_frame(void *arg, struct mbuf **m0, struct i struct ip_fw_args args; struct m_tag *mtag; + bzero(&args, sizeof(args)); + +again: /* fetch start point from rule, if any. remove the tag if present. */ mtag = m_tag_locate(*m0, MTAG_IPFW_RULE, 0, NULL); - if (mtag == NULL) { - args.rule.slot = 0; - } else { + if (mtag != NULL) { args.rule = *((struct ipfw_rule_ref *)(mtag+1)); m_tag_delete(*m0, mtag); if (args.rule.info & IPFW_ONEPASS) @@ -378,14 +379,27 @@ ipfw_check_frame(void *arg, struct mbuf **m0, struct i case IP_FW_DUMMYNET: ret = EACCES; + int dir2; if (ip_dn_io_ptr == NULL) break; /* i.e. drop */ *m0 = NULL; - dir = (dir == PFIL_IN) ? DIR_IN : DIR_OUT; - ip_dn_io_ptr(&m, dir | PROTO_LAYER2, &args); + dir2 = (dir == PFIL_IN) ? DIR_IN : DIR_OUT; + ip_dn_io_ptr(&m, dir2 | PROTO_LAYER2, &args); return 0; + + case IP_FW_NGTEE: + case IP_FW_NETGRAPH: + if (ng_ipfw_input_p == NULL) { + ret = EACCES; + break; /* i.e. drop */ + } + ret = ng_ipfw_input_p(m0, (dir == PFIL_IN) ? DIR_IN : DIR_OUT, + &args, (i == IP_FW_NGTEE) ? 1 : 0); + if (i == IP_FW_NGTEE) /* ignore errors for NGTEE */ + goto again; /* continue with packet */ + break; default: KASSERT(0, ("%s: unknown retval", __func__));