From owner-svn-src-projects@FreeBSD.ORG Mon Aug 11 18:09:38 2014 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id CD605261 for ; Mon, 11 Aug 2014 18:09:38 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id BB11F2C8E for ; Mon, 11 Aug 2014 18:09:38 +0000 (UTC) Received: from melifaro (uid 1268) (envelope-from melifaro@FreeBSD.org) id 2564 by svn.freebsd.org (DragonFly Mail Agent v0.9+); Mon, 11 Aug 2014 18:09:37 +0000 From: Alexander V. Chernikov Date: Mon, 11 Aug 2014 18:09:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r269823 - in projects/ipfw: sbin/ipfw sys/netinet sys/netpfil/ipfw X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <53e906e2.2564.1de9f0da@svn.freebsd.org> X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Aug 2014 18:09:38 -0000 Author: melifaro Date: Mon Aug 11 18:09:37 2014 New Revision: 269823 URL: http://svnweb.freebsd.org/changeset/base/269823 Log: * Add the abilify to lock/unlock given table from changes. Example: # ipfw table si lock # ipfw table si info +++ table(si), set(0) +++ kindex: 0, type: cidr, locked valtype: number, references: 0 algorithm: cidr:radix items: 0, size: 288 # ipfw table si add 4.5.6.7 ignored: 4.5.6.7/32 0 ipfw: Adding record failed: table is locked # ipfw table si unlock # ipfw table si add 4.5.6.7 added: 4.5.6.7/32 0 # ipfw table si lock # ipfw table si delete 4.5.6.7 ignored: 4.5.6.7/32 0 ipfw: Deleting record failed: table is locked # ipfw table si unlock # ipfw table si delete 4.5.6.7 deleted: 4.5.6.7/32 0 Modified: projects/ipfw/sbin/ipfw/ipfw2.h projects/ipfw/sbin/ipfw/tables.c projects/ipfw/sys/netinet/ip_fw.h projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c Modified: projects/ipfw/sbin/ipfw/ipfw2.h ============================================================================== --- projects/ipfw/sbin/ipfw/ipfw2.h Mon Aug 11 17:45:41 2014 (r269822) +++ projects/ipfw/sbin/ipfw/ipfw2.h Mon Aug 11 18:09:37 2014 (r269823) @@ -225,6 +225,8 @@ enum tokens { TOK_TALIST, TOK_FTYPE, TOK_ATOMIC, + TOK_LOCK, + TOK_UNLOCK, }; /* * the following macro returns an error message if we run out of Modified: projects/ipfw/sbin/ipfw/tables.c ============================================================================== --- projects/ipfw/sbin/ipfw/tables.c Mon Aug 11 17:45:41 2014 (r269822) +++ projects/ipfw/sbin/ipfw/tables.c Mon Aug 11 18:09:37 2014 (r269823) @@ -59,6 +59,7 @@ static int table_do_swap(ipfw_obj_header static void table_create(ipfw_obj_header *oh, int ac, char *av[]); static void table_modify(ipfw_obj_header *oh, int ac, char *av[]); static void table_lookup(ipfw_obj_header *oh, int ac, char *av[]); +static void table_lock(ipfw_obj_header *oh, int lock); static int table_swap(ipfw_obj_header *oh, char *second); static int table_get_info(ipfw_obj_header *oh, ipfw_xtable_info *i); static int table_show_info(ipfw_xtable_info *i, void *arg); @@ -115,6 +116,8 @@ static struct _s_x tablecmds[] = { { "list", TOK_LIST }, { "lookup", TOK_LOOKUP }, { "atomic", TOK_ATOMIC }, + { "lock", TOK_LOCK }, + { "unlock", TOK_UNLOCK }, { NULL, 0 } }; @@ -240,6 +243,10 @@ ipfw_table_handler(int ac, char *av[]) NEED1("second table name required"); table_swap(&oh, *av); break; + case TOK_LOCK: + case TOK_UNLOCK: + table_lock(&oh, (tcmd == TOK_LOCK)); + break; case TOK_DETAIL: case TOK_INFO: arg = (tcmd == TOK_DETAIL) ? (void *)1 : NULL; @@ -297,6 +304,7 @@ static struct _s_x tablenewcmds[] = { { "valtype", TOK_VALTYPE }, { "algo", TOK_ALGO }, { "limit", TOK_LIMIT }, + { "locked", TOK_LOCK }, { NULL, 0 } }; @@ -440,6 +448,9 @@ table_create(ipfw_obj_header *oh, int ac strlcpy(xi.algoname, *av, sizeof(xi.algoname)); ac--; av++; break; + case TOK_LOCK: + xi.flags |= IPFW_TGFLAGS_LOCKED; + break; } } @@ -485,10 +496,6 @@ table_modify(ipfw_obj_header *oh, int ac sz = sizeof(tbuf); memset(&xi, 0, sizeof(xi)); - /* Set some defaults to preserve compability */ - xi.type = IPFW_TABLE_CIDR; - xi.vtype = IPFW_VTYPE_U32; - while (ac > 0) { if ((tcmd = match_token(tablenewcmds, *av)) == -1) errx(EX_USAGE, "unknown option: %s", *av); @@ -542,6 +549,25 @@ table_do_modify(ipfw_obj_header *oh, ipf return (error); } + +/* + * Locks or unlocks given table + */ +static void +table_lock(ipfw_obj_header *oh, int lock) +{ + ipfw_xtable_info xi; + int error; + + memset(&xi, 0, sizeof(xi)); + + xi.mflags |= IPFW_TMFLAGS_LOCK; + xi.flags |= (lock != 0) ? IPFW_TGFLAGS_LOCKED : 0; + + if ((error = table_do_modify(oh, &xi)) != 0) + err(EX_OSERR, "Table %s failed", lock != 0 ? "lock" : "unlock"); +} + /* * Destroys given table specified by @oh->ntlv. * Returns 0 on success. @@ -713,7 +739,10 @@ table_show_info(ipfw_xtable_info *i, voi snprintf(tvtype, sizeof(tvtype), "%s", vtype); printf("--- table(%s), set(%u) ---\n", i->tablename, i->set); - printf(" kindex: %d, type: %s\n", i->kidx, ttype); + if ((i->flags & IPFW_TGFLAGS_LOCKED) != 0) + printf(" kindex: %d, type: %s, locked\n", i->kidx, ttype); + else + printf(" kindex: %d, type: %s\n", i->kidx, ttype); printf(" valtype: %s, references: %u\n", tvtype, i->refcnt); printf(" algorithm: %s\n", i->algoname); printf(" items: %u, size: %u\n", i->count, i->size); @@ -1007,6 +1036,9 @@ table_modify_record(ipfw_obj_header *oh, case ENOENT: etxt = "record not found"; break; + case EACCES: + etxt = "table is locked"; + break; default: etxt = strerror(error); } Modified: projects/ipfw/sys/netinet/ip_fw.h ============================================================================== --- projects/ipfw/sys/netinet/ip_fw.h Mon Aug 11 17:45:41 2014 (r269822) +++ projects/ipfw/sys/netinet/ip_fw.h Mon Aug 11 18:09:37 2014 (r269823) @@ -866,7 +866,7 @@ typedef struct _ipfw_xtable_info { uint8_t vtype; /* value type (u32) */ uint8_t vftype; /* value format type (ip,number)*/ uint16_t mflags; /* modification flags */ - uint16_t spare; + uint16_t flags; /* generic table flags */ uint32_t set; /* set table is in */ uint32_t kidx; /* kernel index */ uint32_t refcnt; /* number of references */ @@ -877,13 +877,18 @@ typedef struct _ipfw_xtable_info { char algoname[64]; /* algorithm name */ ipfw_ta_tinfo ta_info; /* additional algo stats */ } ipfw_xtable_info; +/* Generic table flags */ +#define IPFW_TGFLAGS_LOCKED 0x01 /* Tables is locked from changes*/ +/* Table type-specific flags */ #define IPFW_TFFLAG_SRCIP 0x01 #define IPFW_TFFLAG_DSTIP 0x02 #define IPFW_TFFLAG_SRCPORT 0x04 #define IPFW_TFFLAG_DSTPORT 0x08 #define IPFW_TFFLAG_PROTO 0x10 -#define IPFW_TMFLAGS_FTYPE 0x01 /* Change ftype field */ -#define IPFW_TMFLAGS_LIMIT 0x02 /* Change limit value */ +/* Table modification flags */ +#define IPFW_TMFLAGS_FTYPE 0x0001 /* Change ftype field */ +#define IPFW_TMFLAGS_LIMIT 0x0002 /* Change limit value */ +#define IPFW_TMFLAGS_LOCK 0x0004 /* Change table lock state */ typedef struct _ipfw_iface_info { char ifname[64]; /* interface name */ Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c ============================================================================== --- projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c Mon Aug 11 17:45:41 2014 (r269822) +++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c Mon Aug 11 18:09:37 2014 (r269823) @@ -76,7 +76,7 @@ struct table_config { uint8_t vtype; /* value type */ uint8_t vftype; /* value format type */ uint8_t tflags; /* type flags */ - uint8_t spare0; + uint8_t locked; /* 1 if locked from changes */ uint32_t count; /* Number of records */ uint32_t limit; /* Max number of records */ uint8_t linked; /* 1 if already linked */ @@ -210,6 +210,11 @@ add_table_entry(struct ip_fw_chain *ch, return (EINVAL); } + if (tc->locked != 0) { + IPFW_UH_WUNLOCK(ch); + return (EACCES); + } + /* Try to exit early on limit hit */ if ((error = check_table_limit(tc, tei)) != 0 && count == 1) { IPFW_UH_WUNLOCK(ch); @@ -439,6 +444,11 @@ del_table_entry(struct ip_fw_chain *ch, return (ESRCH); } + if (tc->locked != 0) { + IPFW_UH_WUNLOCK(ch); + return (EACCES); + } + if (tc->no.type != ti->type) { IPFW_UH_WUNLOCK(ch); return (EINVAL); @@ -1616,6 +1626,8 @@ ipfw_modify_table(struct ip_fw_chain *ch tc->vftype = i->vftype; if ((i->mflags & IPFW_TMFLAGS_LIMIT) != 0) tc->limit = i->limit; + if ((i->mflags & IPFW_TMFLAGS_LOCK) != 0) + tc->locked = ((i->flags & IPFW_TGFLAGS_LOCKED) != 0); IPFW_UH_WUNLOCK(ch); return (0); @@ -1704,6 +1716,7 @@ create_table_internal(struct ip_fw_chain tc->vftype = i->vftype; tc->limit = i->limit; + tc->locked = (i->flags & IPFW_TGFLAGS_LOCKED) != 0; IPFW_UH_WLOCK(ch); @@ -1792,6 +1805,7 @@ export_table_info(struct ip_fw_chain *ch i->refcnt = tc->no.refcnt; i->count = tc->count; i->limit = tc->limit; + i->flags |= (tc->locked != 0) ? IPFW_TGFLAGS_LOCKED : 0; i->size = tc->count * sizeof(ipfw_obj_tentry); i->size += sizeof(ipfw_obj_header) + sizeof(ipfw_xtable_info); strlcpy(i->tablename, tc->tablename, sizeof(i->tablename));