socsvn commit: r269435 - soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw

dpl at FreeBSD.org dpl at FreeBSD.org
Thu Jun 12 09:57:34 UTC 2014


Author: dpl
Date: Thu Jun 12 09:57:33 2014
New Revision: 269435
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=269435

Log:
  Finished second uops. Let's clear that XXX now.
  

Modified:
  soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_fw2.c
  soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.h

Modified: soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_fw2.c
==============================================================================
--- soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_fw2.c	Thu Jun 12 09:24:17 2014	(r269434)
+++ soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_fw2.c	Thu Jun 12 09:57:33 2014	(r269435)
@@ -1713,119 +1713,15 @@
 			case O_SKIPTO:
 				rule_skipto(&match, &l, &cmd, &skip_or, &f_pos, f, pktlen, chain, cmd, tablearg);
 			    continue;
-			    break;	/* not reached */
+			    break;	/* NOTREACHED */
 
-			case O_CALLRETURN: {
-				/*
-				 * Implementation of `subroutine' call/return,
-				 * in the stack carried in an mbuf tag. This
-				 * is different from `skipto' in that any call
-				 * address is possible (`skipto' must prevent
-				 * backward jumps to avoid endless loops).
-				 * We have `return' action when F_NOT flag is
-				 * present. The `m_tag_id' field is used as
-				 * stack pointer.
-				 */
-				struct m_tag *mtag;
-				uint16_t jmpto, *stack;
-
-#define	IS_CALL		((cmd->len & F_NOT) == 0)
-#define	IS_RETURN	((cmd->len & F_NOT) != 0)
-				/*
-				 * Hand-rolled version of m_tag_locate() with
-				 * wildcard `type'.
-				 * If not already tagged, allocate new tag.
-				 */
-				mtag = m_tag_first(m);
-				while (mtag != NULL) {
-					if (mtag->m_tag_cookie ==
-					    MTAG_IPFW_CALL)
-						break;
-					mtag = m_tag_next(m, mtag);
-				}
-				if (mtag == NULL && IS_CALL) {
-					mtag = m_tag_alloc(MTAG_IPFW_CALL, 0,
-					    IPFW_CALLSTACK_SIZE *
-					    sizeof(uint16_t), M_NOWAIT);
-					if (mtag != NULL)
-						m_tag_prepend(m, mtag);
-				}
-
-				/*
-				 * On error both `call' and `return' just
-				 * continue with next rule.
-				 */
-				if (IS_RETURN && (mtag == NULL ||
-				    mtag->m_tag_id == 0)) {
-					l = 0;		/* exit inner loop */
-					break;
-				}
-				if (IS_CALL && (mtag == NULL ||
-				    mtag->m_tag_id >= IPFW_CALLSTACK_SIZE)) {
-					printf("ipfw: call stack error, "
-					    "go to next rule\n");
-					l = 0;		/* exit inner loop */
-					break;
-				}
-
-				IPFW_INC_RULE_COUNTER(f, pktlen);
-				stack = (uint16_t *)(mtag + 1);
-
-				/*
-				 * The `call' action may use cached f_pos
-				 * (in f->next_rule), whose version is written
-				 * in f->next_rule.
-				 * The `return' action, however, doesn't have
-				 * fixed jump address in cmd->arg1 and can't use
-				 * cache.
-				 */
-				if (IS_CALL) {
-					stack[mtag->m_tag_id] = f->rulenum;
-					mtag->m_tag_id++;
-			    		f_pos = jump_fast(chain, f, cmd->arg1,
-					    tablearg, 1);
-				} else {	/* `return' action */
-					mtag->m_tag_id--;
-					jmpto = stack[mtag->m_tag_id] + 1;
-					f_pos = ipfw_find_rule(chain, jmpto, 0);
-				}
-
-				/*
-				 * Skip disabled rules, and re-enter
-				 * the inner loop with the correct
-				 * f_pos, f, l and cmd.
-				 * Also clear cmdlen and skip_or
-				 */
-				for (; f_pos < chain->n_rules - 1 &&
-				    (V_set_disable &
-				    (1 << chain->map[f_pos]->set)); f_pos++)
-					;
-				/* Re-enter the inner loop at the dest rule. */
-				f = chain->map[f_pos];
-				l = f->cmd_len;
-				cmd = f->cmd;
-				cmdlen = 0;
-				skip_or = 0;
+			case O_CALLRETURN:
+				rule_callreturn(cmd, m, f, chain, tablearg, pktlen, &skip_or, &cmdlen, &f_pos, &l);
 				continue;
 				break;	/* NOTREACHED */
-			}
-#undef IS_CALL
-#undef IS_RETURN
 
 			case O_REJECT:
-				/*
-				 * Drop the packet and send a reject notice
-				 * if the packet is not ICMP (or is an ICMP
-				 * query), and it is not multicast/broadcast.
-				 */
-				if (hlen > 0 && is_ipv4 && offset == 0 &&
-				    (proto != IPPROTO_ICMP ||
-				     is_icmp_query(ICMP(ulp))) &&
-				    !(m->m_flags & (M_BCAST|M_MCAST)) &&
-				    !IN_MULTICAST(ntohl(dst_ip.s_addr))) {
-					send_reject(args, cmd->arg1, iplen, ip);
-					m = args->m;
-				}
+				rule_reject(hlen, is_ipv4, offset, proto, ulp, m, dst_ip, args, cmd, iplen, ip);
 				/* FALLTHROUGH */
 #ifdef INET6
 			case O_UNREACH6:
@@ -1861,111 +1757,21 @@
 				rule_ngtee(args, f_pos, chain, cmd, &retval, &l, &done);
 				break;
 
-			case O_SETFIB: {
-				uint32_t fib;
-
-				IPFW_INC_RULE_COUNTER(f, pktlen);
-				fib = IP_FW_ARG_TABLEARG(cmd->arg1);
-				if (fib >= rt_numfibs)
-					fib = 0;
-				M_SETFIB(m, fib);
-				args->f_id.fib = fib;
-				l = 0;		/* exit inner loop */
+			case O_SETFIB:
+				rule_setfib(f, pkglen, cmd, rt_numfibs, m, args, &l);
 				break;
-		        }
-
-			case O_SETDSCP: {
-				uint16_t code;
-
-				code = IP_FW_ARG_TABLEARG(cmd->arg1) & 0x3F;
-				l = 0;		/* exit inner loop */
-				if (is_ipv4) {
-					uint16_t a;
-
-					a = ip->ip_tos;
-					ip->ip_tos = (code << 2) | (ip->ip_tos & 0x03);
-					a += ntohs(ip->ip_sum) - ip->ip_tos;
-					ip->ip_sum = htons(a);
-				} else if (is_ipv6) {
-					uint8_t *v;
-
-					v = &((struct ip6_hdr *)ip)->ip6_vfc;
-					*v = (*v & 0xF0) | (code >> 2);
-					v++;
-					*v = (*v & 0x3F) | ((code & 0x03) << 6);
-				} else
-					break;
 
-				IPFW_INC_RULE_COUNTER(f, pktlen);
+			case O_SETDSCP:
+				rule_setdscp(cmd,);
 				break;
-			}
 
 			case O_NAT:
-				l = 0;          /* exit inner loop */
-				done = 1;       /* exit outer loop */
- 				if (!IPFW_NAT_LOADED) {
-				    retval = IP_FW_DENY;
-				    break;
-				}
-
-				struct cfg_nat *t;
-				int nat_id;
-
-				set_match(args, f_pos, chain);
-				/* Check if this is 'global' nat rule */
-				if (cmd->arg1 == 0) {
-					retval = ipfw_nat_ptr(args, NULL, m);
-					break;
-				}
-				t = ((ipfw_insn_nat *)cmd)->nat;
-				if (t == NULL) {
-					nat_id = IP_FW_ARG_TABLEARG(cmd->arg1);
-					t = (*lookup_nat_ptr)(&chain->nat, nat_id);
-
-					if (t == NULL) {
-					    retval = IP_FW_DENY;
-					    break;
-					}
-					if (cmd->arg1 != IP_FW_TABLEARG)
-					    ((ipfw_insn_nat *)cmd)->nat = t;
-				}
-				retval = ipfw_nat_ptr(args, t, m);
+				rule_nat(args, f_pos, chain, cmd, &retval, &done, &l);
 				break;
 
-			case O_REASS: {
-				int ip_off;
-
-				IPFW_INC_RULE_COUNTER(f, pktlen);
-				l = 0;	/* in any case exit inner loop */
-				ip_off = ntohs(ip->ip_off);
-
-				/* if not fragmented, go to next rule */
-				if ((ip_off & (IP_MF | IP_OFFMASK)) == 0)
-				    break;
-
-				args->m = m = ip_reass(m);
-
-				/*
-				 * do IP header checksum fixup.
-				 */
-				if (m == NULL) { /* fragment got swallowed */
-				    retval = IP_FW_DENY;
-				} else { /* good, packet complete */
-				    int hlen;
-
-				    ip = mtod(m, struct ip *);
-				    hlen = ip->ip_hl << 2;
-				    ip->ip_sum = 0;
-				    if (hlen == sizeof(struct ip))
-					ip->ip_sum = in_cksum_hdr(ip);
-				    else
-					ip->ip_sum = in_cksum(m, hlen);
-				    retval = IP_FW_REASS;
-				    set_match(args, f_pos, chain);
-				}
-				done = 1;	/* exit outer loop */
+			case O_REASS:
+				rule_reass(f, pktlen, ip, args, m, &retval, &done, &l);
 				break;
-			}
 
 			default:
 				panic("-- unknown opcode %d\n", cmd->opcode);

Modified: soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.h
==============================================================================
--- soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.h	Thu Jun 12 09:24:17 2014	(r269434)
+++ soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.h	Thu Jun 12 09:57:33 2014	(r269435)
@@ -26,7 +26,7 @@
 	 * packet with the ports info.
 	 */
 	if (offset != 0)
-		break;
+		return;
 	if (proto == IPPROTO_TCP ||
 		proto == IPPROTO_UDP)
 		*match = check_uidgid(
@@ -164,10 +164,10 @@
 		else if (v == 6) /* dscp */
 		    key = (ip->ip_tos >> 2) & 0x3f;
 		else if (offset != 0)
-		    break;
+		    return;
 		else if (proto != IPPROTO_TCP &&
 			proto != IPPROTO_UDP)
-		    break;
+		    return;
 		else if (v == 2)
 		    key = htonl(dst_port);
 		else if (v == 3)
@@ -193,12 +193,12 @@
 		    key = htonl(key);
 		} else
 #endif /* !USERSPACE */
-		    break;
+		    return;
 	    }
 	    *match = ipfw_lookup_table(chain,
 		cmd->arg1, key, &v);
 	    if (!(*match))
-		break;
+			return;
 	    if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
 		*match =
 		    ((ipfw_insn_u32 *)cmd)->d[0] == v;
@@ -265,7 +265,7 @@
 			args->f_id.src_ip;
 
 		    if (addr < d[0])
-			    break;
+			    return;
 		    addr -= d[0]; /* subtract base */
 		    *match = (addr < cmd->arg1) &&
 			( d[ 1 + (addr>>5)] &
@@ -413,7 +413,7 @@
 		v++;
 		x |= *v >> 6;
 	} else
-		break;
+		return;
 
 	/* DSCP bitmask is stored as low_u32 high_u32 */
 	if (x > 32)
@@ -524,7 +524,7 @@
 	*match = 1;
 	at = pf_find_mtag(m);
 	if (at != NULL && at->qid != 0)
-		break;
+		return;
 	mtag = m_tag_get(PACKET_TAG_PF,
 		sizeof(struct pf_mtag), M_NOWAIT | M_ZERO);
 	if (mtag == NULL) {
@@ -733,14 +733,14 @@
 	struct inpcbinfo *pi;
 	
 	if (is_ipv6) /* XXX can we remove this ? */
-		break;
+		return;
 
 	if (proto == IPPROTO_TCP)
 		pi = &V_tcbinfo;
 	else if (proto == IPPROTO_UDP)
 		pi = &V_udbinfo;
 	else
-		break;
+		return;
 
 	/*
 	 * XXXRW: so_user_cookie should almost
@@ -781,7 +781,7 @@
 	if (cmdlen == 1) {
 		*match = m_tag_locate(m, MTAG_IPFW,
 		    tag, NULL) != NULL;
-		break;
+		return;
 	}
 
 	/* we have ranges */
@@ -939,19 +939,135 @@
 }
 
 inline void
-rule_callreturn(ipfw_insn *cmd, int *cmdlen, struct mbuf *m, int *l, struct ip_fw *f, int pktlen, uint32_t *tablearg, jmpto, f_pos, struct ip_fw_chain *chain, int *skip_or)
+rule_callreturn(ipfw_insn *cmd, struct mbuf *m, struct ip_fw *f, struct ip_fw_chain *chain, uint32_t tablearg, int pktlen, int *skip_or, int *cmdlen, int *f_pos, int *l)
 {
+	/*
+	 * Implementation of `subroutine' call/return,
+	 * in the stack carried in an mbuf tag. This
+	 * is different from `skipto' in that any call
+	 * address is possible (`skipto' must prevent
+	 * backward jumps to avoid endless loops).
+	 * We have `return' action when F_NOT flag is
+	 * present. The `m_tag_id' field is used as
+	 * stack pointer.
+	 */
+	struct m_tag *mtag;
+	uint16_t jmpto, *stack;
+
+#define	IS_CALL		((cmd->len & F_NOT) == 0)
+#define	IS_RETURN	((cmd->len & F_NOT) != 0)
+	/*
+	 * Hand-rolled version of m_tag_locate() with
+	 * wildcard `type'.
+	 * If not already tagged, allocate new tag.
+	 */
+	mtag = m_tag_first(m);
+	while (mtag != NULL) {
+		if (mtag->m_tag_cookie ==
+		    MTAG_IPFW_CALL)
+			break;
+		mtag = m_tag_next(m, mtag);
+	}
+	if (mtag == NULL && IS_CALL) {
+		mtag = m_tag_alloc(MTAG_IPFW_CALL, 0,
+		    IPFW_CALLSTACK_SIZE *
+		    sizeof(uint16_t), M_NOWAIT);
+		if (mtag != NULL)
+			m_tag_prepend(m, mtag);
+	}
+
+	/*
+	 * On error both `call' and `return' just
+	 * continue with next rule.
+	 */
+	if (IS_RETURN && (mtag == NULL ||
+	    mtag->m_tag_id == 0)) {
+		l = 0;		/* exit inner loop */
+		break;
+	}
+	if (IS_CALL && (mtag == NULL ||
+	    mtag->m_tag_id >= IPFW_CALLSTACK_SIZE)) {
+		printf("ipfw: call stack error, "
+		    "go to next rule\n");
+		l = 0;		/* exit inner loop */
+		break;
+	}
+
+	IPFW_INC_RULE_COUNTER(f, pktlen);
+	stack = (uint16_t *)(mtag + 1);
+
+	/*
+	 * The `call' action may use cached f_pos
+	 * (in f->next_rule), whose version is written
+	 * in f->next_rule.
+	 * The `return' action, however, doesn't have
+	 * fixed jump address in cmd->arg1 and can't use
+	 * cache.
+	 */
+	if (IS_CALL) {
+		stack[mtag->m_tag_id] = f->rulenum;
+		mtag->m_tag_id++;
+    		(*f_pos) = jump_fast(chain, f, cmd->arg1,
+		    tablearg, 1);
+	} else {	/* `return' action */
+		mtag->m_tag_id--;
+		jmpto = stack[mtag->m_tag_id] + 1;
+		(*f_pos) = ipfw_find_rule(chain, jmpto, 0);
+	}
+
+	/*
+	 * Skip disabled rules, and re-enter
+	 * the inner loop with the correct
+	 * f_pos, f, l and cmd.
+	 * Also clear cmdlen and skip_or
+	 */
+	for (; (*f_pos) < chain->n_rules - 1 &&
+	    (V_set_disable &
+	    (1 << chain->map[(*f_pos)]->set)); (*f_pos)++)
+		;
+	/* Re-enter the inner loop at the dest rule. */
+	f = chain->map[(*f_pos)];
+	*l = f->cmd_len;
+	cmd = f->cmd;
+	*cmdlen = 0;
+	*skip_or = 0;
+#undef IS_CALL
+#undef IS_RETURN
 }
 
 inline void
-rule_reject(u_int hlen, int is_ipv4 u_short offset, uint8_t proto, void *void *ulp, struct mbuf *m, struct in_addr *dst_ip, struct ip_fw_args *args, ipfw_insn *cmd, uint16_t iplen struct ip *ip)
+rule_reject(u_int hlen, int is_ipv4 u_short offset, uint8_t proto, void *ulp, struct mbuf *m, struct in_addr *dst_ip, struct ip_fw_args *args, ipfw_insn *cmd, uint16_t iplen struct ip *ip)
 {
+	/*
+	 * Drop the packet and send a reject notice
+	 * if the packet is not ICMP (or is an ICMP
+	 * query), and it is not multicast/broadcast.
+	 */
+	if (hlen > 0 && is_ipv4 && offset == 0 &&
+	    (proto != IPPROTO_ICMP ||
+	     is_icmp_query(ICMP(ulp))) &&
+	    !(m->m_flags & (M_BCAST|M_MCAST)) &&
+	    !IN_MULTICAST(ntohl(dst_ip.s_addr))) {
+		send_reject(args, cmd->arg1, iplen, ip);
+		m = args->m;
+	}
 }
 
 #ifdef INET6
 inline void
-rule_unreach6(u_int hlen, int is_ipv4 u_short offset, uint8_t proto, icmp6_type, struct mbuf *m, struct ip_fw_args *args, ipfw_insn *cmd, struct ip *ip)
+rule_unreach6(u_int hlen, int is_ipv4 u_short offset, uint8_t proto, uint8_t icmp6_type, struct mbuf *m, struct ip_fw_args *args, ipfw_insn *cmd, struct ip *ip)
 {
+	if (hlen > 0 && is_ipv6 &&
+	    ((offset & IP6F_OFF_MASK) == 0) &&
+	    (proto != IPPROTO_ICMPV6 ||
+	     (is_icmp6_query(icmp6_type) == 1)) &&
+	    !(m->m_flags & (M_BCAST|M_MCAST)) &&
+	    !IN6_IS_ADDR_MULTICAST(&args->f_id.dst_ip6)) {
+		send_reject6(
+		    args, cmd->arg1, hlen,
+		    (struct ip6_hdr *)ip);
+		m = args->m;
+	}
 }
 #endif /* INET6 */
 
@@ -1021,21 +1137,112 @@
 	*done = 1;       /* exit outer loop */
 }
 
+/* XXX typeof rt_numfibs? */
 inline void
 rule_setfib(struct ip_fw *f, int pktlen, ipfw_insn *cmd, rt_numfibs, struct mbuf *m, struct ip_fw_args *args, int *l)
 {
+	uint32_t fib;
+
+	IPFW_INC_RULE_COUNTER(f, pktlen);
+	fib = IP_FW_ARG_TABLEARG(cmd->arg1);
+	if (fib >= rt_numfibs)
+		fib = 0;
+	M_SETFIB(m, fib);
+	args->f_id.fib = fib;
+	*l = 0;		/* exit inner loop */
 }
 
 inline void
-rule_setdscp(ipfw_insn *cmd, int *l, int is_ipv4 a, int is_ipv6 f, int pktlen)
+rule_setdscp(ipfw_insn *cmd, int is_ipv4, int is_ipv6, struct ip_fw *f, int pktlen, int *l)
 {
-}
+	uint16_t code;
+
+	code = IP_FW_ARG_TABLEARG(cmd->arg1) & 0x3F;
+	l = 0;		/* exit inner loop */
+	if (is_ipv4) {
+		uint16_t a;
+
+		a = ip->ip_tos;
+		ip->ip_tos = (code << 2) | (ip->ip_tos & 0x03);
+		a += ntohs(ip->ip_sum) - ip->ip_tos;
+		ip->ip_sum = htons(a);
+	} else if (is_ipv6) {
+		uint8_t *v;
+
+		v = &((struct ip6_hdr *)ip)->ip6_vfc;
+		*v = (*v & 0xF0) | (code >> 2);
+		v++;
+		*v = (*v & 0x3F) | ((code & 0x03) << 6);
+	} else
+		return;
 
+	IPFW_INC_RULE_COUNTER(f, pktlen);
+}
 inline void
-rule_nat(int *l, int *done, int *retval, struct ip_fw_args *args, int f_pos, struct ip_fw_chain *chain, ipfw_insn *cmd, struct ip_fw_chain *chain)
+rule_nat(struct ip_fw_args *args, int f_pos, struct ip_fw_chain *chain, ipfw_insn *cmd, int *retval, int *done, int *l)
 {
+	*l = 0;          /* exit inner loop */
+	*done = 1;       /* exit outer loop */
+ 				if (!IPFW_NAT_LOADED) {
+	    retval = IP_FW_DENY;
+	    return;
+	}
+
+	struct cfg_nat *t;
+	int nat_id;
+
+	set_match(args, f_pos, chain);
+	/* Check if this is 'global' nat rule */
+	if (cmd->arg1 == 0) {
+		retval = ipfw_nat_ptr(args, NULL, m);
+		return;
+	}
+	t = ((ipfw_insn_nat *)cmd)->nat;
+	if (t == NULL) {
+		nat_id = IP_FW_ARG_TABLEARG(cmd->arg1);
+		t = (*lookup_nat_ptr)(&chain->nat, nat_id);
+
+		if (t == NULL) {
+		    *retval = IP_FW_DENY;
+		    return;
+		}
+		if (cmd->arg1 != IP_FW_TABLEARG)
+		    ((ipfw_insn_nat *)cmd)->nat = t;
+	}
+	*retval = ipfw_nat_ptr(args, t, m);
 }
 
-inlinue void rule_reass(struct ip_fw *f, int pktlen, int *l, ip_off, struct ip *ip, struct ip_fw_args *args, struct mbuf *m, int *retval, int *done)
+inlinue void rule_reass(struct ip_fw *f, int pktlen, struct ip *ip, struct ip_fw_args *args, struct mbuf *m, int *retval, int *done, int *l)
 {
+	int ip_off;
+
+	IPFW_INC_RULE_COUNTER(f, pktlen);
+	*l = 0;	/* in any case exit inner loop */
+	ip_off = ntohs(ip->ip_off);
+
+	/* if not fragmented, go to next rule */
+	if ((ip_off & (IP_MF | IP_OFFMASK)) == 0)
+	    return;
+
+	args->m = m = ip_reass(m);
+
+	/*
+	 * do IP header checksum fixup.
+	 */
+	if (m == NULL) { /* fragment got swallowed */
+	    *retval = IP_FW_DENY;
+	} else { /* good, packet complete */
+	    int hlen;
+
+	    ip = mtod(m, struct ip *);
+	    hlen = ip->ip_hl << 2;
+	    ip->ip_sum = 0;
+	    if (hlen == sizeof(struct ip))
+			ip->ip_sum = in_cksum_hdr(ip);
+	    else
+			ip->ip_sum = in_cksum(m, hlen);
+		*retval = IP_FW_REASS;
+		set_match(args, f_pos, chain);
+	}
+	*done = 1;	/* exit outer loop */
 }


More information about the svn-soc-all mailing list