--- sys/netpfil/ipfw/ip_fw_pfil.c.orig 2015-11-18 11:44:31.000000000 +0700 +++ sys/netpfil/ipfw/ip_fw_pfil.c 2016-10-13 20:19:43.704582000 +0700 @@ -303,11 +303,12 @@ ipfw_check_frame(void *arg, struct mbuf struct ip_fw_args args; struct m_tag *mtag; + bzero(&args, sizeof(args)); + +again: /* fetch start point from rule, if any */ mtag = m_tag_locate(*m0, MTAG_IPFW_RULE, 0, NULL); - if (mtag == NULL) { - args.rule.slot = 0; - } else { + if (mtag != NULL) { /* dummynet packet, already partially processed */ struct ipfw_rule_ref *r; @@ -369,16 +370,28 @@ ipfw_check_frame(void *arg, struct mbuf case IP_FW_DUMMYNET: ret = EACCES; - int dir; + int dir2; if (ip_dn_io_ptr == NULL) break; /* i.e. drop */ *m0 = NULL; - dir = PROTO_LAYER2 | (dst ? DIR_OUT : DIR_IN); - ip_dn_io_ptr(&m, dir, &args); + dir2 = PROTO_LAYER2 | (dst ? DIR_OUT : DIR_IN); + ip_dn_io_ptr(&m, dir2, &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__)); }