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