From owner-p4-projects@FreeBSD.ORG Sun Jun 28 21:50:39 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 030481065676; Sun, 28 Jun 2009 21:50:39 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 936E21065675 for ; Sun, 28 Jun 2009 21:50:38 +0000 (UTC) (envelope-from tsel@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 809658FC27 for ; Sun, 28 Jun 2009 21:50:38 +0000 (UTC) (envelope-from tsel@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n5SLocQB096903 for ; Sun, 28 Jun 2009 21:50:38 GMT (envelope-from tsel@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n5SLocS0096901 for perforce@freebsd.org; Sun, 28 Jun 2009 21:50:38 GMT (envelope-from tsel@FreeBSD.org) Date: Sun, 28 Jun 2009 21:50:38 GMT Message-Id: <200906282150.n5SLocS0096901@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to tsel@FreeBSD.org using -f From: Tatsiana Elavaya To: Perforce Change Reviews Cc: Subject: PERFORCE change 165359 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 28 Jun 2009 21:50:40 -0000 http://perforce.freebsd.org/chv.cgi?CH=165359 Change 165359 by tsel@tsel_mz on 2009/06/28 21:50:04 Finish per rule optimization instruction rewrite. Add negative match optimization Affected files ... .. //depot/projects/soc2009/tsel_ipfw/sbin/ipfw/ipfw2.c#8 edit .. //depot/projects/soc2009/tsel_ipfw/sys/netinet/ip_fw2.c#5 edit Differences ... ==== //depot/projects/soc2009/tsel_ipfw/sbin/ipfw/ipfw2.c#8 (text+ko) ==== @@ -1619,8 +1619,14 @@ break; case O_OPTIMIZE: - if (co.verbose) - printf(" [optimize %d %u]", cmd->arg1, ((ipfw_insn_u32*)cmd)->d[0]); + if (co.verbose) { + int i, cnt = (F_LEN(cmd) - 1) * 2; + printf(" [optimize"); + for (i = 0; i < cnt; i++) + if (((ipfw_insn_u16*)cmd)->ports[i]) + printf(" %d", ((ipfw_insn_u16*)cmd)->ports[i]); + printf("]"); + } break; default: @@ -2067,9 +2073,9 @@ int insn_eq(ipfw_insn *a, ipfw_insn *b) { - if ((a->len | b->len) & (F_NOT | F_OR)) + if ((a->len | b->len) & F_OR) return 0; - if (F_LEN(a) != F_LEN(b) || a->arg1 != b->arg1 || a->opcode != b->opcode) + if (a->len != b->len || a->arg1 != b->arg1 || a->opcode != b->opcode) return 0; switch (a->opcode) { case O_IP_SRC: @@ -2228,7 +2234,7 @@ &labels_max, &group_count, NULL, 0) == -1) { errx(EX_DATAERR, "optimization not supported"); } - labels_max *= 8; + labels_max *= 8 / 2; /* one label is 2 bits long */ group_count = 0; LIST_FOREACH_SAFE(g, head, group_entries, g_tmp) { @@ -2239,7 +2245,7 @@ LIST_REMOVE(g, group_entries); continue; } - g->label = group_count++; + g->label = (group_count++) + 1; printf("sorted: %d; opcode %d; match_count %d; rank %d\n", g->label, LIST_FIRST(&g->match_head)->cmd->opcode, g->match_count, g->rank); @@ -2251,7 +2257,7 @@ optimization_setup(int enable, int labels) { if (enable) { - labels = (labels + 7)/8; + labels = (labels + 3)/4; if (sysctlbyname("net.inet.ip.fw.optimization_buf", NULL, 0, &labels, sizeof(labels)) == -1) { errx(EX_DATAERR, "optimization not supported"); @@ -2333,24 +2339,13 @@ for (i = 0; rules[i]; i++) { ipfw_insn *cmd, *rcmd; struct insn_match *m; - ipfw_insn_u32 *optimize_cmd; + ipfw_insn_u16 *optimize_cmd; + int optimize_cnt = 0; int l; if (LIST_EMPTY(&match_rules[i].rule_head)) continue; - printf("rule %d; before sort: ", rules[i]->rulenum); - LIST_FOREACH(m, &match_rules[i].rule_head, rule_entries) { - printf("optimize %d:%d; ", m->cmd->opcode, m->group->rank); - } - printf("\n"); - insn_match_rule_cmd_sort(&match_rules[i].rule_head, insn_match_rule_cmd_cmp); - printf("rule %d; after sort: ", rules[i]->rulenum); - LIST_FOREACH(m, &match_rules[i].rule_head, rule_entries) { - printf("optimize %d:%d; ", m->cmd->opcode, m->group->rank); - } - printf("\n"); - memcpy(orule, rules[i], sizeof(struct ip_fw) - 4); cmd = orule->cmd; rcmd = rules[i]->cmd; @@ -2362,12 +2357,29 @@ l -= F_LEN(rcmd); } - // FIXME - optimize_cmd = (ipfw_insn_u32 *) cmd; - optimize_cmd->o.len = F_INSN_SIZE(ipfw_insn_u32); + optimize_cmd = (ipfw_insn_u16 *) cmd; optimize_cmd->o.opcode = O_OPTIMIZE; optimize_cmd->o.arg1 = 0; - optimize_cmd->d[0] = 0; + + /* + printf("rule %d; before sort: ", rules[i]->rulenum); + LIST_FOREACH(m, &match_rules[i].rule_head, rule_entries) { + printf("optimize %d:%d; ", m->cmd->opcode, m->group->rank); + } + printf("\n"); + */ + insn_match_rule_cmd_sort(&match_rules[i].rule_head, insn_match_rule_cmd_cmp); + //printf("rule %d; after sort: ", rules[i]->rulenum); + LIST_FOREACH(m, &match_rules[i].rule_head, rule_entries) { + //printf("optimize %d:%d; ", m->cmd->opcode, m->group->rank); + optimize_cmd->ports[optimize_cnt] = m->group->label; + if (optimize_cnt % 2 == 0) + optimize_cmd->ports[optimize_cnt + 1] = 0; + optimize_cnt++; + } + //printf("\n"); + + optimize_cmd->o.len = F_INSN_SIZE(ipfw_insn) + (optimize_cnt + 1) / 2; cmd += optimize_cmd->o.len; orule->cmd_len += optimize_cmd->o.len; orule->act_ofs += optimize_cmd->o.len; @@ -2394,35 +2406,10 @@ } rcmd += F_LEN(rcmd); } - printf(" insn original: "); + + printf("before optimization: "); show_ipfw(rules[i], 0, 0); - printf("insn reordered: "); - show_ipfw(orule, 0, 0); - - /* - LIST_FOREACH_SAFE(m, &match_rules[i].rule_head, rule_entries, m_tmp) { - ipfw_insn_u32 optimize_cmd; - int cmd_offset = ((int32_t*) m->cmd) - ((int32_t*) rules[i]->cmd); - - optimize_cmd.o.len = F_INSN_SIZE(ipfw_insn_u32); - optimize_cmd.o.opcode = O_OPTIMIZE; - optimize_cmd.o.arg1 = m->cmd->opcode; - optimize_cmd.d[0] = m->group->label; - if (cmd_offset >= orule->act_ofs) - errx(EX_DATAERR, "optimizing action: rule %d\n", orule->rulenum); - if (orule->cmd_len + F_LEN(&optimize_cmd.o) > 255) - errx(EX_DATAERR, "option list is too long: rule %d", orule->rulenum); - memcpy(orule->cmd + cmd_offset + F_LEN(&optimize_cmd.o), - orule->cmd + cmd_offset, - (orule->cmd_len - cmd_offset) * 4); - memcpy(orule->cmd + cmd_offset, &optimize_cmd, F_LEN(&optimize_cmd.o) * 4); - orule->cmd_len += F_LEN(&optimize_cmd.o); - orule->act_ofs += F_LEN(&optimize_cmd.o); - // printf("rule %d; cmd %d; offset %d\n", orule->rulenum, m->cmd->opcode, cmd_offset); - } - */ - l = orule->rulenum & 0xffff; if (do_cmd(IP_FW_DEL, &l, sizeof(l))) errx(EX_DATAERR, "rule %u: setsockopt(IP_FW_DEL)", orule->rulenum); @@ -2434,7 +2421,8 @@ show_ipfw(orule, 0, 0); } - optimization_setup(1, group_count); + if (group_count) + optimization_setup(1, group_count); } static int ==== //depot/projects/soc2009/tsel_ipfw/sys/netinet/ip_fw2.c#5 (text+ko) ==== @@ -362,7 +362,7 @@ if (sz > OPTIMIZATION_BUF_MAX) sz = OPTIMIZATION_BUF_MAX; - /* do not shrink buffers. ruleset may contain old o_optimize insn's */ + /* do not shrink buffers. ruleset may contain old o_optimize instructions */ if (sz <= *(int *)arg1) return 0; @@ -2378,8 +2378,10 @@ /* end of ipv6 variables */ int is_ipv4 = 0; -#define GET_OPTIMIZ_LABEL(a) (optimiz_buf ? optimiz_buf[(a) / 32] & (1 << ((a) % 32)) : 0) -#define SET_OPTIMIZ_LABEL(a) (optimiz_buf ? optimiz_buf[(a) / 32] |= (1 << ((a) % 32)) : 0) +#define GET_OPTIMIZ_LABEL(a) (optimiz_buf ? optimiz_buf[((a) - 1) / 32] & (1 << (((a) - 1) % 32)) : 0) +#define SET_OPTIMIZ_LABEL(a) (optimiz_buf ? optimiz_buf[((a) - 1) / 32] |= (1 << (((a) - 1) % 32)) : 0) +#define GET_NEG_OPTIMIZ_LABEL(a) GET_OPTIMIZ_LABEL((a) + V_optimization_buf_sz*4) +#define SET_NEG_OPTIMIZ_LABEL(a) SET_OPTIMIZ_LABEL((a) + V_optimization_buf_sz*4) uint32_t *optimiz_buf = NULL; uint32_t optimiz_buf_ind = 0; @@ -2693,9 +2695,10 @@ ipfw_insn *cmd; uint32_t tablearg = 0; int l, cmdlen, skip_or; /* skip rest of OR block */ - int optimiz_match = 0; + ipfw_insn_u16 *optimiz_cmd = NULL; + int optimiz_ind = 0, optimiz_match = 0; #ifdef IPFW_OPTIMIZE_DEBUG - ipfw_insn_u32 *optimiz_cmd = NULL; + int optimiz_match_neg = 0; #endif again: @@ -2729,23 +2732,39 @@ } match = 0; /* set to 1 if we succeed */ - if (V_optimization_enable && optimiz_match > 0 && cmd->opcode != O_OPTIMIZE) { -#ifdef IPFW_OPTIMIZE_DEBUG - if (optimiz_cmd->o.arg1 != cmd->opcode || - optimiz_cmd->d[0] + 1 != optimiz_match) { - printf("ipfw: optimization error %d %d; expected %d %d\n", - cmd->opcode, optimiz_match - 1, - optimiz_cmd->o.arg1, optimiz_cmd->d[0] + 1); - } + if (V_optimization_enable && optimiz_cmd != NULL && cmd->opcode != O_OPTIMIZE) { + int label = optimiz_cmd->ports[optimiz_ind]; + + if (optimiz_ind >= (F_LEN(&optimiz_cmd->o) - 1) * 2 || label == 0) { + optimiz_cmd = NULL; + optimiz_ind = 0; + optimiz_match = 0; + } else { + optimiz_ind++; + if (GET_OPTIMIZ_LABEL(label)) { + optimiz_match = label; + printf("ipfw: rule %d: optimized %d %d\n", f->rulenum, cmd->opcode, optimiz_match); +#ifndef IPFW_OPTIMIZE_DEBUG + continue; #else - printf("ipfw: optimized %d %d\n", cmd->opcode, optimiz_match - 1); - optimiz_match = 0; - match = !(cmd->len & F_NOT); + optimiz_match_neg = 0; #endif - } + } if (GET_NEG_OPTIMIZ_LABEL(label)) { + optimiz_match = label; + printf("ipfw: rule %d: negative optimized %d %d\n", f->rulenum, cmd->opcode, optimiz_match); #ifndef IPFW_OPTIMIZE_DEBUG - else + goto next_rule; +#else + optimiz_match_neg = 1; #endif + + } else { + optimiz_match = -label; + } + } + + } + switch (cmd->opcode) { /* * The first set of opcodes compares the packet's @@ -3291,23 +3310,25 @@ break; } case O_OPTIMIZE: { - int label = ((ipfw_insn_u32 *) cmd)->d[0]; + optimiz_cmd = (ipfw_insn_u16 *) cmd; + optimiz_ind = 0; - if (!V_optimization_enable || !optimiz_buf || - label > V_optimization_buf_sz * 8) + if (!V_optimization_enable || !optimiz_buf) { + optimiz_cmd = NULL; continue; + } + + for (int i = 0; i < (F_LEN(cmd) - 1) * 2; i++) + if (optimiz_cmd->ports[i] > V_optimization_buf_sz * 8 / 2) { + printf("ipfw: invalid O_OPTIMIZE instruction. ignoring"); + optimiz_cmd = NULL; + continue; + } if (optimiz_match) { printf("ipfw: unexpected O_OPTIMIZE instruction. ignoring"); continue; } -#ifdef IPFW_OPTIMIZE_DEBUG - optimiz_cmd = (ipfw_insn_u32 *) cmd; -#endif - if (GET_OPTIMIZ_LABEL(label)) - optimiz_match = label + 1; - else - optimiz_match = -(label + 1); continue; } @@ -3613,26 +3634,25 @@ panic("-- unknown opcode %d\n", cmd->opcode); } /* end of switch() on opcodes */ + if (cmd->len & F_NOT) + match = !match; + #ifdef IPFW_OPTIMIZE_DEBUG - if (optimiz_match > 0 && !match) - printf("ipfw: optimization error: cmd mismatch %d (optimiz_cmd=%d) %d\n", cmd->opcode, optimiz_cmd->o.arg1, optimiz_match); + if (optimiz_match > 0 && (match != !optimiz_match_neg || cmd->len & F_OR)) + printf("ipfw: rule %d: optimization error: cmd mismatch %d (optimiz_ind=%d, neg=%d) %d\n", f->rulenum, cmd->opcode, optimiz_ind, optimiz_match_neg, optimiz_match); #endif if (V_optimization_enable) { - if (match) { - if (optimiz_match < 0) { - optimiz_match = -optimiz_match - 1; + if (optimiz_match < 0) { + optimiz_match = -optimiz_match; + if (match) SET_OPTIMIZ_LABEL(optimiz_match); - printf("ipfw: set optimize match %d %d\n", cmd->opcode, optimiz_match); - optimiz_match = 0; - } - } else { - optimiz_match = 0; + else + SET_NEG_OPTIMIZ_LABEL(optimiz_match); + printf("ipfw: rule %d: set %soptimize match %d %d\n", f->rulenum, match ? "" : "negative ", cmd->opcode, optimiz_match); } + optimiz_match = 0; } - if (cmd->len & F_NOT) - match = !match; - if (match) { if (cmd->len & F_OR) skip_or = 1; @@ -4230,7 +4250,7 @@ break; case O_OPTIMIZE: - if (cmdlen < F_INSN_SIZE(ipfw_insn_u32)) + if (cmdlen < F_INSN_SIZE(ipfw_insn_u16)) goto bad_size; break;