From owner-svn-src-head@FreeBSD.ORG Sun Apr 26 10:53:36 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id DC614D21; Sun, 26 Apr 2015 10:53:36 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id CAB6415D2; Sun, 26 Apr 2015 10:53:36 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t3QAraCU053736; Sun, 26 Apr 2015 10:53:36 GMT (envelope-from melifaro@FreeBSD.org) Received: (from melifaro@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t3QAraVt053733; Sun, 26 Apr 2015 10:53:36 GMT (envelope-from melifaro@FreeBSD.org) Message-Id: <201504261053.t3QAraVt053733@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: melifaro set sender to melifaro@FreeBSD.org using -f From: "Alexander V. Chernikov" Date: Sun, 26 Apr 2015 10:53:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r282004 - head/sbin/ipfw X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 26 Apr 2015 10:53:37 -0000 Author: melifaro Date: Sun Apr 26 10:53:35 2015 New Revision: 282004 URL: https://svnweb.freebsd.org/changeset/base/282004 Log: Generalize object reference handling in ipfw rules. No ABI changes. Modified: head/sbin/ipfw/ipfw2.c head/sbin/ipfw/ipfw2.h head/sbin/ipfw/tables.c Modified: head/sbin/ipfw/ipfw2.c ============================================================================== --- head/sbin/ipfw/ipfw2.c Sun Apr 26 10:52:37 2015 (r282003) +++ head/sbin/ipfw/ipfw2.c Sun Apr 26 10:53:35 2015 (r282004) @@ -375,6 +375,13 @@ static int ipfw_show_config(struct cmdli ipfw_cfg_lheader *cfg, size_t sz, int ac, char **av); static void ipfw_list_tifaces(void); +struct tidx; +static uint16_t pack_object(struct tidx *tstate, char *name, int otype); +static uint16_t pack_table(struct tidx *tstate, char *name); + +static char *table_search_ctlv(ipfw_obj_ctlv *ctlv, uint16_t idx); +static void object_sort_ctlv(ipfw_obj_ctlv *ctlv); + /* * Simple string buffer API. * Used to simplify buffer passing between function and for @@ -2558,6 +2565,7 @@ ipfw_show_config(struct cmdline_opts *co if (cfg->flags & IPFW_CFG_GET_STATIC) { /* We've requested static rules */ if (ctlv->head.type == IPFW_TLV_TBLNAME_LIST) { + object_sort_ctlv(ctlv); fo->tstate = ctlv; readsz += ctlv->head.length; ctlv = (ipfw_obj_ctlv *)((caddr_t)ctlv + @@ -2724,19 +2732,18 @@ struct tidx { }; static uint16_t -pack_table(struct tidx *tstate, char *name) +pack_object(struct tidx *tstate, char *name, int otype) { int i; ipfw_obj_ntlv *ntlv; - if (table_check_name(name) != 0) - return (0); - for (i = 0; i < tstate->count; i++) { if (strcmp(tstate->idx[i].name, name) != 0) continue; if (tstate->idx[i].set != tstate->set) continue; + if (tstate->idx[i].head.type != otype) + continue; return (tstate->idx[i].idx); } @@ -2752,7 +2759,7 @@ pack_table(struct tidx *tstate, char *na ntlv = &tstate->idx[i]; memset(ntlv, 0, sizeof(ipfw_obj_ntlv)); strlcpy(ntlv->name, name, sizeof(ntlv->name)); - ntlv->head.type = IPFW_TLV_TBL_NAME; + ntlv->head.type = otype; ntlv->head.length = sizeof(ipfw_obj_ntlv); ntlv->set = tstate->set; ntlv->idx = ++tstate->counter; @@ -2761,6 +2768,16 @@ pack_table(struct tidx *tstate, char *na return (ntlv->idx); } +static uint16_t +pack_table(struct tidx *tstate, char *name) +{ + + if (table_check_name(name) != 0) + return (0); + + return (pack_object(tstate, name, IPFW_TLV_TBL_NAME)); +} + static void fill_table(ipfw_insn *cmd, char *av, uint8_t opcode, struct tidx *tstate) { @@ -3611,7 +3628,6 @@ compile_rule(char *av[], uint32_t *rbuf, break; } else goto chkarg; - case TOK_QUEUE: action->opcode = O_QUEUE; goto chkarg; @@ -4656,6 +4672,101 @@ done: *rbufsize = (char *)dst - (char *)rule; } +static int +compare_ntlv(const void *_a, const void *_b) +{ + ipfw_obj_ntlv *a, *b; + + a = (ipfw_obj_ntlv *)_a; + b = (ipfw_obj_ntlv *)_b; + + if (a->set < b->set) + return (-1); + else if (a->set > b->set) + return (1); + + if (a->idx < b->idx) + return (-1); + else if (a->idx > b->idx) + return (1); + + if (a->head.type < b->head.type) + return (-1); + else if (a->head.type > b->head.type) + return (1); + + return (0); +} + +/* + * Provide kernel with sorted list of referenced objects + */ +static void +object_sort_ctlv(ipfw_obj_ctlv *ctlv) +{ + + qsort(ctlv + 1, ctlv->count, ctlv->objsize, compare_ntlv); +} + +struct object_kt { + uint16_t uidx; + uint16_t type; +}; +static int +compare_object_kntlv(const void *k, const void *v) +{ + ipfw_obj_ntlv *ntlv; + struct object_kt key; + + key = *((struct object_kt *)k); + ntlv = (ipfw_obj_ntlv *)v; + + if (key.uidx < ntlv->idx) + return (-1); + else if (key.uidx > ntlv->idx) + return (1); + + if (key.type < ntlv->head.type) + return (-1); + else if (key.type > ntlv->head.type) + return (1); + + return (0); +} + +/* + * Finds object name in @ctlv by @idx and @type. + * Uses the following facts: + * 1) All TLVs are the same size + * 2) Kernel implementation provides already sorted list. + * + * Returns table name or NULL. + */ +static char * +object_search_ctlv(ipfw_obj_ctlv *ctlv, uint16_t idx, uint16_t type) +{ + ipfw_obj_ntlv *ntlv; + struct object_kt key; + + key.uidx = idx; + key.type = type; + + ntlv = bsearch(&key, (ctlv + 1), ctlv->count, ctlv->objsize, + compare_object_kntlv); + + if (ntlv != 0) + return (ntlv->name); + + return (NULL); +} + +static char * +table_search_ctlv(ipfw_obj_ctlv *ctlv, uint16_t idx) +{ + + return (object_search_ctlv(ctlv, idx, IPFW_TLV_TBL_NAME)); +} + /* * Adds one or more rules to ipfw chain. * Data layout: @@ -4724,7 +4835,7 @@ ipfw_add(char *av[]) ctlv->count = ts.count; ctlv->objsize = sizeof(ipfw_obj_ntlv); memcpy(ctlv + 1, ts.idx, tlen); - table_sort_ctlv(ctlv); + object_sort_ctlv(ctlv); tstate = ctlv; /* Rule next */ ctlv = (ipfw_obj_ctlv *)((caddr_t)ctlv + ctlv->head.length); Modified: head/sbin/ipfw/ipfw2.h ============================================================================== --- head/sbin/ipfw/ipfw2.h Sun Apr 26 10:52:37 2015 (r282003) +++ head/sbin/ipfw/ipfw2.h Sun Apr 26 10:53:35 2015 (r282004) @@ -344,8 +344,6 @@ int fill_ext6hdr(struct _ipfw_insn *cmd, /* tables.c */ struct _ipfw_obj_ctlv; -char *table_search_ctlv(struct _ipfw_obj_ctlv *ctlv, uint16_t idx); -void table_sort_ctlv(struct _ipfw_obj_ctlv *ctlv); int table_check_name(char *tablename); void ipfw_list_ta(int ac, char *av[]); void ipfw_list_values(int ac, char *av[]); Modified: head/sbin/ipfw/tables.c ============================================================================== --- head/sbin/ipfw/tables.c Sun Apr 26 10:52:37 2015 (r282003) +++ head/sbin/ipfw/tables.c Sun Apr 26 10:53:35 2015 (r282004) @@ -1937,73 +1937,6 @@ ipfw_list_values(int ac, char *av[]) } int -compare_ntlv(const void *_a, const void *_b) -{ - ipfw_obj_ntlv *a, *b; - - a = (ipfw_obj_ntlv *)_a; - b = (ipfw_obj_ntlv *)_b; - - if (a->set < b->set) - return (-1); - else if (a->set > b->set) - return (1); - - if (a->idx < b->idx) - return (-1); - else if (a->idx > b->idx) - return (1); - - return (0); -} - -int -compare_kntlv(const void *k, const void *v) -{ - ipfw_obj_ntlv *ntlv; - uint16_t key; - - key = *((uint16_t *)k); - ntlv = (ipfw_obj_ntlv *)v; - - if (key < ntlv->idx) - return (-1); - else if (key > ntlv->idx) - return (1); - - return (0); -} - -/* - * Finds table name in @ctlv by @idx. - * Uses the following facts: - * 1) All TLVs are the same size - * 2) Kernel implementation provides already sorted list. - * - * Returns table name or NULL. - */ -char * -table_search_ctlv(ipfw_obj_ctlv *ctlv, uint16_t idx) -{ - ipfw_obj_ntlv *ntlv; - - ntlv = bsearch(&idx, (ctlv + 1), ctlv->count, ctlv->objsize, - compare_kntlv); - - if (ntlv != 0) - return (ntlv->name); - - return (NULL); -} - -void -table_sort_ctlv(ipfw_obj_ctlv *ctlv) -{ - - qsort(ctlv + 1, ctlv->count, ctlv->objsize, compare_ntlv); -} - -int table_check_name(char *tablename) { int c, i, l;