Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 27 Oct 2018 07:32:26 +0000 (UTC)
From:      Eugene Grosbein <eugen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r339810 - head/sys/netpfil/ipfw
Message-ID:  <201810270732.w9R7WQYu021532@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <ufm@ufm.su>

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__));



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201810270732.w9R7WQYu021532>