socsvn commit: r269431 - soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw
dpl at FreeBSD.org
dpl at FreeBSD.org
Thu Jun 12 08:40:40 UTC 2014
Author: dpl
Date: Thu Jun 12 08:40:37 2014
New Revision: 269431
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=269431
Log:
Added up to rule_skipto().
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 04:47:14 2014 (r269430)
+++ soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_fw2.c Thu Jun 12 08:40:37 2014 (r269431)
@@ -780,7 +780,7 @@
*/
static inline void
set_match(struct ip_fw_args *args, int slot,
- struct ip_fw_chain *chain)
+ struct ip_fw_chain *chain)
{
args->rule.chain_id = chain->id;
args->rule.slot = slot + 1; /* we use 0 as a marker */
@@ -1625,116 +1625,21 @@
rule_ip4(&match, is_ipv4);
break;
- case O_TAG: {
- struct m_tag *mtag;
- uint32_t tag = IP_FW_ARG_TABLEARG(cmd->arg1);
-
- /* Packet is already tagged with this tag? */
- mtag = m_tag_locate(m, MTAG_IPFW, tag, NULL);
-
- /* We have `untag' action when F_NOT flag is
- * present. And we must remove this mtag from
- * mbuf and reset `match' to zero (`match' will
- * be inversed later).
- * Otherwise we should allocate new mtag and
- * push it into mbuf.
- */
- if (cmd->len & F_NOT) { /* `untag' action */
- if (mtag != NULL)
- m_tag_delete(m, mtag);
- match = 0;
- } else {
- if (mtag == NULL) {
- mtag = m_tag_alloc( MTAG_IPFW,
- tag, 0, M_NOWAIT);
- if (mtag != NULL)
- m_tag_prepend(m, mtag);
- }
- match = 1;
- }
+ case O_TAG:
+ rule_tag(&match, cmd, m);
break;
- }
case O_FIB: /* try match the specified fib */
- if (args->f_id.fib == cmd->arg1)
- match = 1;
+ rule_fib(&match, args, cmd);
break;
- case O_SOCKARG: {
-#ifndef USERSPACE /* not supported in userspace */
- struct inpcb *inp = args->inp;
- struct inpcbinfo *pi;
-
- if (is_ipv6) /* XXX can we remove this ? */
- break;
-
- if (proto == IPPROTO_TCP)
- pi = &V_tcbinfo;
- else if (proto == IPPROTO_UDP)
- pi = &V_udbinfo;
- else
- break;
-
- /*
- * XXXRW: so_user_cookie should almost
- * certainly be inp_user_cookie?
- */
-
- /* For incomming packet, lookup up the
- inpcb using the src/dest ip/port tuple */
- if (inp == NULL) {
- inp = in_pcblookup(pi,
- src_ip, htons(src_port),
- dst_ip, htons(dst_port),
- INPLOOKUP_RLOCKPCB, NULL);
- if (inp != NULL) {
- tablearg =
- inp->inp_socket->so_user_cookie;
- if (tablearg)
- match = 1;
- INP_RUNLOCK(inp);
- }
- } else {
- if (inp->inp_socket) {
- tablearg =
- inp->inp_socket->so_user_cookie;
- if (tablearg)
- match = 1;
- }
- }
-#endif /* !USERSPACE */
+ case O_SOCKARG:
+ rule_sockarg();
break;
- }
-
- case O_TAGGED: {
- struct m_tag *mtag;
- uint32_t tag = IP_FW_ARG_TABLEARG(cmd->arg1);
-
- if (cmdlen == 1) {
- match = m_tag_locate(m, MTAG_IPFW,
- tag, NULL) != NULL;
- break;
- }
- /* we have ranges */
- for (mtag = m_tag_first(m);
- mtag != NULL && !match;
- mtag = m_tag_next(m, mtag)) {
- uint16_t *p;
- int i;
-
- if (mtag->m_tag_cookie != MTAG_IPFW)
- continue;
-
- p = ((ipfw_insn_u16 *)cmd)->ports;
- i = cmdlen - 1;
- for(; !match && i > 0; i--, p += 2)
- match =
- mtag->m_tag_id >= p[0] &&
- mtag->m_tag_id <= p[1];
- }
+ case O_TAGGED:
+ rule_tagged(&match, cmd, cmdlen, m);
break;
- }
/*
* The second set of opcodes represents 'actions',
@@ -1779,99 +1684,30 @@
*/
case O_LIMIT:
case O_KEEP_STATE:
- if (ipfw_install_state(f,
- (ipfw_insn_limit *)cmd, args, tablearg)) {
- /* error or limit violation */
- retval = IP_FW_DENY;
- l = 0; /* exit inner loop */
- done = 1; /* exit outer loop */
- }
- match = 1;
+ rule_keep_state(&match, f, cmd, args, tablearg, &retval, &l, &done);
break;
case O_PROBE_STATE:
case O_CHECK_STATE:
- /*
- * dynamic rules are checked at the first
- * keep-state or check-state occurrence,
- * with the result being stored in dyn_dir.
- * The compiler introduces a PROBE_STATE
- * instruction for us when we have a
- * KEEP_STATE (because PROBE_STATE needs
- * to be run first).
- */
- if (dyn_dir == MATCH_UNKNOWN &&
- (q = ipfw_lookup_dyn_rule(&args->f_id,
- &dyn_dir, proto == IPPROTO_TCP ?
- TCP(ulp) : NULL))
- != NULL) {
- /*
- * Found dynamic entry, update stats
- * and jump to the 'action' part of
- * the parent rule by setting
- * f, cmd, l and clearing cmdlen.
- */
- IPFW_INC_DYN_COUNTER(q, pktlen);
- /* XXX we would like to have f_pos
- * readily accessible in the dynamic
- * rule, instead of having to
- * lookup q->rule.
- */
- f = q->rule;
- f_pos = ipfw_find_rule(chain,
- f->rulenum, f->id);
- cmd = ACTION_PTR(f);
- l = f->cmd_len - f->act_ofs;
- ipfw_dyn_unlock(q);
- cmdlen = 0;
- match = 1;
- break;
- }
- /*
- * Dynamic entry not found. If CHECK_STATE,
- * skip to next rule, if PROBE_STATE just
- * ignore and continue with next opcode.
- */
- if (cmd->opcode == O_CHECK_STATE)
- l = 0; /* exit inner loop */
- match = 1;
+ rule_check_state(&match);
break;
case O_ACCEPT:
- retval = 0; /* accept */
- l = 0; /* exit inner loop */
- done = 1; /* exit outer loop */
+ rule_accept(&retval, &l, &done);
break;
case O_PIPE:
case O_QUEUE:
- set_match(args, f_pos, chain);
- args->rule.info = IP_FW_ARG_TABLEARG(cmd->arg1);
- if (cmd->opcode == O_PIPE)
- args->rule.info |= IPFW_IS_PIPE;
- if (V_fw_one_pass)
- args->rule.info |= IPFW_ONEPASS;
- retval = IP_FW_DUMMYNET;
- l = 0; /* exit inner loop */
- done = 1; /* exit outer loop */
+ rule_queue(args, f_pos, chain, cmd, &retval, &l, &done);
break;
case O_DIVERT:
case O_TEE:
- if (args->eh) /* not on layer 2 */
- break;
- /* otherwise this is terminal */
- l = 0; /* exit inner loop */
- done = 1; /* exit outer loop */
- retval = (cmd->opcode == O_DIVERT) ?
- IP_FW_DIVERT : IP_FW_TEE;
- set_match(args, f_pos, chain);
- args->rule.info = IP_FW_ARG_TABLEARG(cmd->arg1);
+ rule_tee(&l, &done, &retval, cmd, args, f_pos, chain);
break;
case O_COUNT:
- IPFW_INC_RULE_COUNTER(f, pktlen);
- l = 0; /* exit inner loop */
+ rule_count(&l, f, pktlen);
break;
case O_SKIPTO:
Modified: soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.h
==============================================================================
--- soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.h Thu Jun 12 04:47:14 2014 (r269430)
+++ soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.h Thu Jun 12 08:40:37 2014 (r269431)
@@ -219,7 +219,6 @@
}
-//XXX Speak with mentor about passing both dst_ip and src_ip.
inline void
rule_ip_dst_mask(int *match, int is_ipv4, ipfw_insn *cmd, int cmdlen, struct in_addr *dst_ip, struct in_addr *src_ip)
{
@@ -585,9 +584,8 @@
verify_path(src_ip, NULL, args->f_id.fib)));
}
-// XXX typeof(m)?
inline void
-rule_antispoof(int *match, struct ifnet *oif, u_int hlen, int is_ipv4, int is_ipv6, struct in_addr *src_ip, struct ip_fw_args *args, m)
+rule_antispoof(int *match, struct ifnet *oif, u_int hlen, int is_ipv4, int is_ipv6, struct in_addr *src_ip, struct ip_fw_args *args, struct mbuf *m)
{
/* Outgoing packets automatically pass/match */
if (oif == NULL && hlen > 0 &&
@@ -809,42 +807,139 @@
* The second sets of opcodes. They represent the actions of a rule.
*/
inline void
-rule_keep_state(int *match, f, ipfw_insn *cmd, struct ip_fw_args *args, uint32_t *tablearg, retval, l, done)
+rule_keep_state(int *match, struct ip_fw *f, ipfw_insn *cmd, struct ip_fw_args *args, uint32_t *tablearg, int *retval, int *l, int *done)
{
+ if (ipfw_install_state(f,
+ (ipfw_insn_limit *)cmd, args, tablearg)) {
+ /* error or limit violation */
+ *retval = IP_FW_DENY;
+ *l = 0; /* exit inner loop */
+ *done = 1; /* exit outer loop */
+ }
+ *match = 1;
}
+/* XXX typeof dyn_dir? */
+/* XXX typeof q? */
inline void
-rule_check_state(int *match, dyn_dir, q, struct ip_fw_args *args, uint8_t proto, void *void *ulp, pktlen, f, f_pos, struct ip_fw_chain *chain, ipfw_insn *cmd, int *cmdlen, l)
+rule_check_state(int *match, dyn_dir, q, struct ip_fw_args *args, uint8_t proto, void *ulp, int pktlen, struct ip_fw *f, int *f_pos, struct ip_fw_chain *chain, ipfw_insn *cmd, int *cmdlen, int *l)
{
+ /*
+ * dynamic rules are checked at the first
+ * keep-state or check-state occurrence,
+ * with the result being stored in dyn_dir.
+ * The compiler introduces a PROBE_STATE
+ * instruction for us when we have a
+ * KEEP_STATE (because PROBE_STATE needs
+ * to be run first).
+ */
+ if (dyn_dir == MATCH_UNKNOWN &&
+ (q = ipfw_lookup_dyn_rule(&args->f_id,
+ &dyn_dir, proto == IPPROTO_TCP ?
+ TCP(ulp) : NULL))
+ != NULL) {
+ /*
+ * Found dynamic entry, update stats
+ * and jump to the 'action' part of
+ * the parent rule by setting
+ * f, cmd, l and clearing cmdlen.
+ */
+ IPFW_INC_DYN_COUNTER(q, pktlen);
+ /* XXX we would like to have f_pos
+ * readily accessible in the dynamic
+ * rule, instead of having to
+ * lookup q->rule.
+ */
+ f = q->rule;
+ *f_pos = ipfw_find_rule(chain,
+ f->rulenum, f->id);
+ cmd = ACTION_PTR(f);
+ *l = f->cmd_len - f->act_ofs;
+ ipfw_dyn_unlock(q);
+ *cmdlen = 0;
+ *match = 1;
+ return;
+ }
+ /*
+ * Dynamic entry not found. If CHECK_STATE,
+ * skip to next rule, if PROBE_STATE just
+ * ignore and continue with next opcode.
+ */
+ if (cmd->opcode == O_CHECK_STATE)
+ *l = 0; /* exit inner loop */
+ *match = 1;
}
inline void
-rule_accept(retval, l, done)
+rule_accept(int *retval, int *l, int *done)
{
+ *retval = 0; /* accept */
+ *l = 0; /* exit inner loop */
+ *done = 1; /* exit outer loop */
}
inline void
-rule_queue(args, f_pos, struct ip_fw_chain *chain, ipfw_insn *cmd, retval, l, done)
+rule_queue(struct ip_fw_args *args, int f_pos, struct ip_fw_chain *chain, ipfw_insn *cmd, int *retval, int *l, int *done)
{
+ set_match(args, f_pos, chain);
+ args->rule.info = IP_FW_ARG_TABLEARG(cmd->arg1);
+ if (cmd->opcode == O_PIPE)
+ args->rule.info |= IPFW_IS_PIPE;
+ if (V_fw_one_pass)
+ args->rule.info |= IPFW_ONEPASS;
+ *retval = IP_FW_DUMMYNET;
+ *l = 0; /* exit inner loop */
+ *done = 1; /* exit outer loop */
}
inline void
-rule_tee(args, l, done, retval, ipfw_insn *cmd, struct ip_fw_args *args, f_pos, struct ip_fw_chain *chain)
+rule_tee(int *l, int *done, int *retval, ipfw_insn *cmd, struct ip_fw_args *args, int f_pos, struct ip_fw_chain *chain)
{
+ if (args->eh) /* not on layer 2 */
+ return;
+ /* otherwise this is terminal */
+ *l = 0; /* exit inner loop */
+ *done = 1; /* exit outer loop */
+ *retval = (cmd->opcode == O_DIVERT) ?
+ IP_FW_DIVERT : IP_FW_TEE;
+ set_match(args, f_pos, chain);
+ args->rule.info = IP_FW_ARG_TABLEARG(cmd->arg1);
}
inline void
-rule_count(l, f, pktlen)
+rule_count(int *l, struct ip_fw *f, int pktlen)
{
+ IPFW_INC_RULE_COUNTER(f, pktlen);
+ *l = 0; /* exit inner loop */
}
inline void
-rule_skipto(int *match, f, f_pos, pktlen, struct ip_fw_chain *chain, ipfw_insn *cmd, uint32_t *tablearg, l, ipfw_insn *cmd, int *cmdlen, skip_or)
+rule_skipto(int *match, int *l, ipfw_insn *cmd, int *cmdlen, int *skip_or, int *f_pos, struct ip_fw *f, int pktlen, struct ip_fw_chain *chain, ipfw_insn *cmd, uint32_t tablearg)
{
+ IPFW_INC_RULE_COUNTER(f, pktlen);
+ *f_pos = jump_fast(chain, f, cmd->arg1, tablearg, 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 skipto rule. */
+ f = chain->map[f_pos];
+ *l = f->cmd_len;
+ cmd = f->cmd;
+ *match = 1;
+ *cmdlen = 0;
+ *skip_or = 0;
}
inline void
-rule_callreturn(ipfw_insn *cmd, int *cmdlen, struct mbuf *m, l, f, pktlen, uint32_t *tablearg, jmpto, f_pos, struct ip_fw_chain *chain, skip_or)
+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)
{
}
@@ -862,42 +957,42 @@
inline void
-rule_deny(l, done, retval)
+rule_deny(int *l, int *done, int *retval)
{
}
inline void
-rule_forward_ip(args, q, dyn_dir, ipfw_insn *cmd, sa, retval, l, done)
+rule_forward_ip(args, q, dyn_dir, ipfw_insn *cmd, sa, int *retval, int *l, int *done)
{
}
#ifdef INET6
inline void
-rule_forward_ip6(args, q, f, dun_dir, ipfw_insn *cmd, struct ip_fw_args *args, retval, l, done)
+rule_forward_ip6(args, q, struct ip_fw *f, dun_dir, ipfw_insn *cmd, struct ip_fw_args *args, int *retval, int *l, int *done)
{
}
#endif /* INET6 */
inline void
-rule_ngtee(args, f_pos, struct ip_fw_chain *chain, ipfw_insn *cmd, V_fw_one_pass, retval, l, done)
+rule_ngtee(args, f_pos, struct ip_fw_chain *chain, ipfw_insn *cmd, V_fw_one_pass, int *retval, int *l, int *done)
{
}
inline void
-rule_setfib(f, pktlen, ipfw_insn *cmd, rt_numfibs, struct mbuf *m, struct ip_fw_args *args, l)
+rule_setfib(struct ip_fw *f, int pktlen, ipfw_insn *cmd, rt_numfibs, struct mbuf *m, struct ip_fw_args *args, int *l)
{
}
inline void
-rule_setdscp(ipfw_insn *cmd, l, int is_ipv4 a, int is_ipv6 f, pktlen)
+rule_setdscp(ipfw_insn *cmd, int *l, int is_ipv4 a, int is_ipv6 f, int pktlen)
{
}
inline void
-rule_nat(l, done, retval, struct ip_fw_args *args, f_pos, struct ip_fw_chain *chain, ipfw_insn *cmd, struct ip_fw_chain *chain)
+rule_nat(int *l, int *done, int *retval, struct ip_fw_args *args, f_pos, struct ip_fw_chain *chain, ipfw_insn *cmd, struct ip_fw_chain *chain)
{
}
-inlinue void rule_reass(f, pktlen, l, ip_off, struct ip *ip, struct ip_fw_args *args, struct mbuf *m, retval, done)
+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)
{
}
More information about the svn-soc-all
mailing list