svn commit: r345162 - head/sys/netpfil/ipfw

Gleb Smirnoff glebius at FreeBSD.org
Thu Mar 14 22:28:52 UTC 2019


Author: glebius
Date: Thu Mar 14 22:28:50 2019
New Revision: 345162
URL: https://svnweb.freebsd.org/changeset/base/345162

Log:
  - Add more flags to ip_fw_args. At this changeset only IPFW_ARGS_IN and
    IPFW_ARGS_OUT are utilized. They are intented to substitute the "dir"
    parameter that is often passes together with args.
  - Rename ip_fw_args.oif to ifp and now it is set to either input or
    output interface, depending on IPFW_ARGS_IN/OUT bit set.

Modified:
  head/sys/netpfil/ipfw/ip_dn_io.c
  head/sys/netpfil/ipfw/ip_fw2.c
  head/sys/netpfil/ipfw/ip_fw_dynamic.c
  head/sys/netpfil/ipfw/ip_fw_log.c
  head/sys/netpfil/ipfw/ip_fw_nat.c
  head/sys/netpfil/ipfw/ip_fw_pfil.c
  head/sys/netpfil/ipfw/ip_fw_private.h

Modified: head/sys/netpfil/ipfw/ip_dn_io.c
==============================================================================
--- head/sys/netpfil/ipfw/ip_dn_io.c	Thu Mar 14 22:23:09 2019	(r345161)
+++ head/sys/netpfil/ipfw/ip_dn_io.c	Thu Mar 14 22:28:50 2019	(r345162)
@@ -841,7 +841,7 @@ tag_mbuf(struct mbuf *m, int dir, struct ip_fw_args *f
 	dt->rule = fwa->rule;
 	dt->rule.info &= IPFW_ONEPASS;	/* only keep this info */
 	dt->dn_dir = dir;
-	dt->ifp = fwa->oif;
+	dt->ifp = fwa->flags & IPFW_ARGS_OUT ? fwa->ifp : NULL;
 	/* dt->output tame is updated as we move through */
 	dt->output_time = dn_cfg.curr_time;
 	dt->iphdr_off = (dir & PROTO_LAYER2) ? ETHER_HDR_LEN : 0;

Modified: head/sys/netpfil/ipfw/ip_fw2.c
==============================================================================
--- head/sys/netpfil/ipfw/ip_fw2.c	Thu Mar 14 22:23:09 2019	(r345161)
+++ head/sys/netpfil/ipfw/ip_fw2.c	Thu Mar 14 22:28:50 2019	(r345162)
@@ -1080,13 +1080,11 @@ check_uidgid(ipfw_insn_u32 *insn, struct ip_fw_args *a
 	struct inpcbinfo *pi;
 	struct ipfw_flow_id *id;
 	struct inpcb *pcb, *inp;
-	struct ifnet *oif;
 	int lookupflags;
 	int match;
 
 	id = &args->f_id;
 	inp = args->inp;
-	oif = args->oif;
 
 	/*
 	 * Check to see if the UDP or TCP stack supplied us with
@@ -1124,16 +1122,16 @@ check_uidgid(ipfw_insn_u32 *insn, struct ip_fw_args *a
 	if (*ugid_lookupp == 0) {
 		if (id->addr_type == 6) {
 #ifdef INET6
-			if (oif == NULL)
+			if (args->flags & IPFW_ARGS_IN)
 				pcb = in6_pcblookup_mbuf(pi,
 				    &id->src_ip6, htons(id->src_port),
 				    &id->dst_ip6, htons(id->dst_port),
-				    lookupflags, oif, args->m);
+				    lookupflags, NULL, args->m);
 			else
 				pcb = in6_pcblookup_mbuf(pi,
 				    &id->dst_ip6, htons(id->dst_port),
 				    &id->src_ip6, htons(id->src_port),
-				    lookupflags, oif, args->m);
+				    lookupflags, args->ifp, args->m);
 #else
 			*ugid_lookupp = -1;
 			return (0);
@@ -1141,16 +1139,16 @@ check_uidgid(ipfw_insn_u32 *insn, struct ip_fw_args *a
 		} else {
 			src_ip.s_addr = htonl(id->src_ip);
 			dst_ip.s_addr = htonl(id->dst_ip);
-			if (oif == NULL)
+			if (args->flags & IPFW_ARGS_IN)
 				pcb = in_pcblookup_mbuf(pi,
 				    src_ip, htons(id->src_port),
 				    dst_ip, htons(id->dst_port),
-				    lookupflags, oif, args->m);
+				    lookupflags, NULL, args->m);
 			else
 				pcb = in_pcblookup_mbuf(pi,
 				    dst_ip, htons(id->dst_port),
 				    src_ip, htons(id->src_port),
-				    lookupflags, oif, args->m);
+				    lookupflags, args->ifp, args->m);
 		}
 		if (pcb != NULL) {
 			INP_RLOCK_ASSERT(pcb);
@@ -1263,8 +1261,7 @@ jump_linear(struct ip_fw_chain *chain, struct ip_fw *f
  *	args->eh (in)	Mac header if present, NULL for layer3 packet.
  *	args->L3offset	Number of bytes bypassed if we came from L2.
  *			e.g. often sizeof(eh)  ** NOTYET **
- *	args->oif	Outgoing interface, NULL if packet is incoming.
- *		The incoming interface is in the mbuf. (in)
+ *	args->ifp	Incoming or outgoing interface.
  *	args->divert_rule (in/out)
  *		Skip up to the first rule past this rule number;
  *		upon return, non-zero port number for divert or tee.
@@ -1331,17 +1328,9 @@ ipfw_chk(struct ip_fw_args *args)
 	struct ucred *ucred_cache = NULL;
 #endif
 	int ucred_lookup = 0;
-
-	/*
-	 * oif | args->oif	If NULL, ipfw_chk has been called on the
-	 *	inbound path (ether_input, ip_input).
-	 *	If non-NULL, ipfw_chk has been called on the outbound path
-	 *	(ether_output, ip_output).
-	 */
-	struct ifnet *oif = args->oif;
-
 	int f_pos = 0;		/* index of current rule in the array */
 	int retval = 0;
+	struct ifnet *oif, *iif;
 
 	/*
 	 * hlen	The length of the IP header.
@@ -1724,6 +1713,15 @@ do {								\
 		f_pos = 0;
 	}
 
+	if (args->flags & IPFW_ARGS_IN) {
+		iif = args->ifp;
+		oif = NULL;
+	} else {
+		MPASS(args->flags & IPFW_ARGS_OUT);
+		iif = m->m_pkthdr.rcvif;
+		oif = args->ifp;
+	}
+
 	/*
 	 * Now scan the rules, and parse microinstructions for each rule.
 	 * We have two nested loops and an inner switch. Sometimes we
@@ -1820,8 +1818,8 @@ do {								\
 				break;
 
 			case O_RECV:
-				match = iface_match(m->m_pkthdr.rcvif,
-				    (ipfw_insn_if *)cmd, chain, &tablearg);
+				match = iface_match(iif, (ipfw_insn_if *)cmd,
+				    chain, &tablearg);
 				break;
 
 			case O_XMIT:
@@ -1830,9 +1828,8 @@ do {								\
 				break;
 
 			case O_VIA:
-				match = iface_match(oif ? oif :
-				    m->m_pkthdr.rcvif, (ipfw_insn_if *)cmd,
-				    chain, &tablearg);
+				match = iface_match(args->ifp,
+				    (ipfw_insn_if *)cmd, chain, &tablearg);
 				break;
 
 			case O_MACADDR2:
@@ -2334,7 +2331,7 @@ do {								\
 
 			case O_LOG:
 				ipfw_log(chain, f, hlen, args, m,
-				    oif, offset | ip6f_mf, tablearg, ip);
+				    offset | ip6f_mf, tablearg, ip);
 				match = 1;
 				break;
 
@@ -2344,16 +2341,14 @@ do {								\
 
 			case O_VERREVPATH:
 				/* Outgoing packets automatically pass/match */
-				match = ((oif != NULL) ||
-				    (m->m_pkthdr.rcvif == NULL) ||
+				match = (args->flags & IPFW_ARGS_OUT ||
 				    (
 #ifdef INET6
 				    is_ipv6 ?
 					verify_path6(&(args->f_id.src_ip6),
-					    m->m_pkthdr.rcvif, args->f_id.fib) :
+					    iif, args->f_id.fib) :
 #endif
-				    verify_path(src_ip, m->m_pkthdr.rcvif,
-				        args->f_id.fib)));
+				    verify_path(src_ip, iif, args->f_id.fib)));
 				break;
 
 			case O_VERSRCREACH:
@@ -2379,12 +2374,10 @@ do {								\
 					match =
 #ifdef INET6
 					    is_ipv6 ? verify_path6(
-					        &(args->f_id.src_ip6),
-					        m->m_pkthdr.rcvif,
+					        &(args->f_id.src_ip6), iif,
 						args->f_id.fib) :
 #endif
-					    verify_path(src_ip,
-					    	m->m_pkthdr.rcvif,
+					    verify_path(src_ip, iif,
 					        args->f_id.fib);
 				else
 					match = 1;

Modified: head/sys/netpfil/ipfw/ip_fw_dynamic.c
==============================================================================
--- head/sys/netpfil/ipfw/ip_fw_dynamic.c	Thu Mar 14 22:23:09 2019	(r345161)
+++ head/sys/netpfil/ipfw/ip_fw_dynamic.c	Thu Mar 14 22:28:50 2019	(r345162)
@@ -1173,12 +1173,9 @@ dyn_getscopeid(const struct ip_fw_args *args)
 	 * determine the scope zone id to resolve address scope ambiguity.
 	 */
 	if (IN6_IS_ADDR_LINKLOCAL(&args->f_id.src_ip6) ||
-	    IN6_IS_ADDR_LINKLOCAL(&args->f_id.dst_ip6)) {
-		MPASS(args->oif != NULL ||
-		    args->m->m_pkthdr.rcvif != NULL);
-		return (in6_getscopezone(args->oif != NULL ? args->oif:
-		    args->m->m_pkthdr.rcvif, IPV6_ADDR_SCOPE_LINKLOCAL));
-	}
+	    IN6_IS_ADDR_LINKLOCAL(&args->f_id.dst_ip6))
+		return (in6_getscopezone(args->ifp, IPV6_ADDR_SCOPE_LINKLOCAL));
+
 	return (0);
 }
 

Modified: head/sys/netpfil/ipfw/ip_fw_log.c
==============================================================================
--- head/sys/netpfil/ipfw/ip_fw_log.c	Thu Mar 14 22:23:09 2019	(r345161)
+++ head/sys/netpfil/ipfw/ip_fw_log.c	Thu Mar 14 22:28:50 2019	(r345162)
@@ -99,7 +99,7 @@ __FBSDID("$FreeBSD$");
  */
 void
 ipfw_log(struct ip_fw_chain *chain, struct ip_fw *f, u_int hlen,
-    struct ip_fw_args *args, struct mbuf *m, struct ifnet *oif,
+    struct ip_fw_args *args, struct mbuf *m,
     u_short offset, uint32_t tablearg, struct ip *ip)
 {
 	char *action;
@@ -405,19 +405,14 @@ ipfw_log(struct ip_fw_chain *chain, struct ip_fw *f, u
 		}
 	}
 #ifdef __FreeBSD__
-	if (oif || m->m_pkthdr.rcvif)
-		log(LOG_SECURITY | LOG_INFO,
-		    "ipfw: %d %s %s %s via %s%s\n",
-		    f ? f->rulenum : -1,
-		    action, proto, oif ? "out" : "in",
-		    oif ? oif->if_xname : m->m_pkthdr.rcvif->if_xname,
-		    fragment);
-	else
+	log(LOG_SECURITY | LOG_INFO, "ipfw: %d %s %s %s via %s%s\n",
+	    f ? f->rulenum : -1, action, proto,
+	    args->flags & IPFW_ARGS_OUT ? "out" : "in", args->ifp->if_xname,
+	    fragment);
+#else
+	log(LOG_SECURITY | LOG_INFO, "ipfw: %d %s %s [no if info]%s\n",
+	    f ? f->rulenum : -1, action, proto, fragment);
 #endif
-		log(LOG_SECURITY | LOG_INFO,
-		    "ipfw: %d %s %s [no if info]%s\n",
-		    f ? f->rulenum : -1,
-		    action, proto, fragment);
 	if (limit_reached)
 		log(LOG_SECURITY | LOG_NOTICE,
 		    "ipfw: limit %d reached on entry %d\n",

Modified: head/sys/netpfil/ipfw/ip_fw_nat.c
==============================================================================
--- head/sys/netpfil/ipfw/ip_fw_nat.c	Thu Mar 14 22:23:09 2019	(r345161)
+++ head/sys/netpfil/ipfw/ip_fw_nat.c	Thu Mar 14 22:28:50 2019	(r345162)
@@ -347,7 +347,7 @@ ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, s
 
 	/* Check if this is 'global' instance */
 	if (t == NULL) {
-		if (args->oif == NULL) {
+		if (args->flags & IPFW_ARGS_IN) {
 			/* Wrong direction, skip processing */
 			args->m = mcl;
 			return (IP_FW_NAT);
@@ -374,7 +374,7 @@ ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, s
 			return (IP_FW_NAT);
 		}
 	} else {
-		if (args->oif == NULL)
+		if (args->flags & IPFW_ARGS_IN)
 			retval = LibAliasIn(t->lib, c,
 				mcl->m_len + M_TRAILINGSPACE(mcl));
 		else
@@ -391,7 +391,8 @@ ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, s
 	 *		PKT_ALIAS_DENY_INCOMING flag is set.
 	 */
 	if (retval == PKT_ALIAS_ERROR ||
-	    (args->oif == NULL && (retval == PKT_ALIAS_UNRESOLVED_FRAGMENT ||
+	    ((args->flags & IPFW_ARGS_IN) &&
+	    (retval == PKT_ALIAS_UNRESOLVED_FRAGMENT ||
 	    (retval == PKT_ALIAS_IGNORED &&
 	    (t->mode & PKT_ALIAS_DENY_INCOMING) != 0)))) {
 		/* XXX - should i add some logging? */

Modified: head/sys/netpfil/ipfw/ip_fw_pfil.c
==============================================================================
--- head/sys/netpfil/ipfw/ip_fw_pfil.c	Thu Mar 14 22:23:09 2019	(r345161)
+++ head/sys/netpfil/ipfw/ip_fw_pfil.c	Thu Mar 14 22:28:50 2019	(r345162)
@@ -118,17 +118,16 @@ SYSEND
  * The packet may be consumed.
  */
 static pfil_return_t
-ipfw_check_packet(struct mbuf **m0, struct ifnet *ifp, int dir,
+ipfw_check_packet(struct mbuf **m0, struct ifnet *ifp, int flags,
     void *ruleset __unused, struct inpcb *inp)
 {
 	struct ip_fw_args args;
 	struct m_tag *tag;
 	pfil_return_t ret;
-	int ipfw;
+	int ipfw, dir;
 
-	/* convert dir to IPFW values */
-	dir = (dir & PFIL_IN) ? DIR_IN : DIR_OUT;
-	args.flags = 0;
+	args.flags = (flags & PFIL_IN) ? IPFW_ARGS_IN : IPFW_ARGS_OUT;
+	dir = (flags & PFIL_IN) ? DIR_IN : DIR_OUT;
 again:
 	/*
 	 * extract and remove the tag if present. If we are left
@@ -144,7 +143,7 @@ again:
 	}
 
 	args.m = *m0;
-	args.oif = dir == DIR_OUT ? ifp : NULL;
+	args.ifp = ifp;
 	args.inp = inp;
 
 	ipfw = ipfw_chk(&args);
@@ -198,7 +197,7 @@ again:
 		 * m_tag_find. Outgoing packets may be tagged, so we
 		 * reuse the tag if present.
 		 */
-		tag = (dir == DIR_IN) ? NULL :
+		tag = (flags & PFIL_IN) ? NULL :
 			m_tag_find(*m0, PACKET_TAG_IPFORWARD, NULL);
 		if (tag != NULL) {
 			m_tag_unlink(*m0, tag);
@@ -346,6 +345,7 @@ ipfw_check_frame(struct mbuf **m0, struct ifnet *ifp, 
 	int i;
 
 	args.flags = IPFW_ARGS_ETHER;
+	args.flags |= (dir & PFIL_IN) ? IPFW_ARGS_IN : IPFW_ARGS_OUT;
 again:
 	/* fetch start point from rule, if any.  remove the tag if present. */
 	mtag = m_tag_locate(*m0, MTAG_IPFW_RULE, 0, NULL);
@@ -372,7 +372,7 @@ again:
 	m_adj(m, ETHER_HDR_LEN);	/* strip ethernet header */
 
 	args.m = m;		/* the packet we are looking at		*/
-	args.oif = dir & PFIL_OUT ? ifp: NULL;	/* destination, if any	*/
+	args.ifp = ifp;
 	args.eh = &save_eh;	/* MAC header for bridged/MAC packets	*/
 	args.inp = inp;	/* used by ipfw uid/gid/jail rules	*/
 	i = ipfw_chk(&args);

Modified: head/sys/netpfil/ipfw/ip_fw_private.h
==============================================================================
--- head/sys/netpfil/ipfw/ip_fw_private.h	Thu Mar 14 22:23:09 2019	(r345161)
+++ head/sys/netpfil/ipfw/ip_fw_private.h	Thu Mar 14 22:28:50 2019	(r345162)
@@ -85,12 +85,19 @@ struct _ip6dn_args {
  */
 struct ip_fw_args {
 	uint32_t		flags;
-#define	IPFW_ARGS_ETHER		0x0001	/* has valid ethernet header	*/
-#define	IPFW_ARGS_NH4		0x0002	/* has IPv4 next hop in hopstore */
-#define	IPFW_ARGS_NH6		0x0004	/* has IPv6 next hop in hopstore */
-#define	IPFW_ARGS_NH4PTR	0x0008	/* has IPv4 next hop in next_hop */
-#define	IPFW_ARGS_NH6PTR	0x0010	/* has IPv6 next hop in next_hop6 */
-#define	IPFW_ARGS_REF		0x0020	/* has valid ipfw_rule_ref	*/
+#define	IPFW_ARGS_ETHER		0x00010000	/* valid ethernet header */
+#define	IPFW_ARGS_NH4		0x00020000	/* IPv4 next hop in hopstore */
+#define	IPFW_ARGS_NH6		0x00040000	/* IPv6 next hop in hopstore */
+#define	IPFW_ARGS_NH4PTR	0x00080000	/* IPv4 next hop in next_hop */
+#define	IPFW_ARGS_NH6PTR	0x00100000	/* IPv6 next hop in next_hop6 */
+#define	IPFW_ARGS_REF		0x00200000	/* valid ipfw_rule_ref	*/
+#define	IPFW_ARGS_IN		0x00400000	/* called on input */
+#define	IPFW_ARGS_OUT		0x00800000	/* called on output */
+#define	IPFW_ARGS_IP4		0x01000000	/* belongs to v4 ISR */
+#define	IPFW_ARGS_IP6		0x02000000	/* belongs to v6 ISR */
+#define	IPFW_ARGS_DROP		0x04000000	/* drop it (dummynet) */
+#define	IPFW_ARGS_LENMASK	0x0000ffff	/* length of data in *mem */
+#define	IPFW_ARGS_LENGTH(f)	((f) & IPFW_ARGS_LENMASK)
 	/*
 	 * On return, it points to the matching rule.
 	 * On entry, rule.slot > 0 means the info is valid and
@@ -100,7 +107,7 @@ struct ip_fw_args {
 	 */
 	struct ipfw_rule_ref	rule;	/* match/restart info		*/
 
-	struct ifnet		*oif;	/* output interface		*/
+	struct ifnet		*ifp;	/* input/output interface	*/
 	struct inpcb		*inp;
 	union {
 		/*
@@ -181,7 +188,7 @@ void ipfw_bpf_init(int);
 void ipfw_bpf_uninit(int);
 void ipfw_bpf_mtap2(void *, u_int, struct mbuf *);
 void ipfw_log(struct ip_fw_chain *chain, struct ip_fw *f, u_int hlen,
-    struct ip_fw_args *args, struct mbuf *m, struct ifnet *oif,
+    struct ip_fw_args *args, struct mbuf *m,
     u_short offset, uint32_t tablearg, struct ip *ip);
 VNET_DECLARE(u_int64_t, norule_counter);
 #define	V_norule_counter	VNET(norule_counter)


More information about the svn-src-all mailing list