From owner-freebsd-net@FreeBSD.ORG Thu Jun 5 13:01:27 2014 Return-Path: Delivered-To: net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 3681B8BD; Thu, 5 Jun 2014 13:01:27 +0000 (UTC) Received: from mail-pd0-x235.google.com (mail-pd0-x235.google.com [IPv6:2607:f8b0:400e:c02::235]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id F12542983; Thu, 5 Jun 2014 13:01:26 +0000 (UTC) Received: by mail-pd0-f181.google.com with SMTP id z10so1039749pdj.26 for ; Thu, 05 Jun 2014 06:01:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:references:in-reply-to:subject:date:message-id :mime-version:content-type:thread-index:content-language; bh=+S6/F6pGb4YucabfL/DKazC3jvqnIOGixBU+b2uMu9I=; b=qdLP0TGo52wNBFQGQQZ2SLs+n9Kn1CLyxKE1Gd9peJGZmQ7vKG6aETy9H2RkxeDVj9 fpfwy05LAk0Lc0sS5lBkl4q/okjwvzTGo4vdt2ZAgi7l5Glg+gxAvb7wU/d7cPbvKIhQ nW/xQG9w9NMZ9jmhXKiFb9bUz3a5B3nU7o7Hhbcednl1xqdtSOMRdcSkX9uYOLJs0ssO 2rscae0o/73JLG3WQLFvBg0aMRyE2tWvvc5VumyRW6V3T0LQ061AypZsagaLqXuethAv TGU1KBX488ZpdfAonWCoV1vmH4k74xEDtqQPmYixknUlBJRcH8Brze1aJYpV5gEq9ocd SN6g== X-Received: by 10.68.135.195 with SMTP id pu3mr27300507pbb.10.1401973286482; Thu, 05 Jun 2014 06:01:26 -0700 (PDT) Received: from billwin7 (amx-tls2.starhub.net.sg. [203.116.164.12]) by mx.google.com with ESMTPSA id gg3sm22741670pbc.34.2014.06.05.06.01.21 for (version=TLSv1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 05 Jun 2014 06:01:24 -0700 (PDT) From: "bycn82" To: "'Alexander V. Chernikov'" References: <5379FE3C.6060501@FreeBSD.org> <20140521111002.GB62462@onelab2.iet.unipi.it> <537CEC12.8050404@FreeBSD.org> <20140521204826.GA67124@onelab2.iet.unipi.it> <537E1029.70007@FreeBSD.org> <20140522154740.GA76448@onelab2.iet.unipi.it> <537E2153.1040005@FreeBSD.org> <20140522163812.GA77634@onelab2.iet.unipi.it> <538B2FE5.6070407@FreeBSD.org> <539044E4.1020904@ipfw.ru> In-Reply-To: <539044E4.1020904@ipfw.ru> Subject: RE: [CFT]: ipfw named tables / different tabletypes Date: Thu, 5 Jun 2014 21:01:19 +0800 Message-ID: <000c01cf80be$41194370$c34bca50$@gmail.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_000D_01CF8101.4F3D6DD0" X-Mailer: Microsoft Outlook 14.0 Thread-Index: AQHVthFPJT+R8Q+z/PfZZcF60gm+OADP7m1eASCyZGECMm0rcwKNzWvvAlvxzMYB26ii/AFrQU/SAWbxMPACXuZNZJrVQjzA Content-Language: en-us Cc: 'Luigi Rizzo' , 'FreeBSD Net' X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 Jun 2014 13:01:27 -0000 This is a multipart message in MIME format. ------=_NextPart_000_000D_01CF8101.4F3D6DD0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Alex, Here is my patch, with this patch, the ipfw can support below commands,=20 root@FB10Head:~ # ipfw table 1 name saleteam root@FB10Head:~ # ipfw table 1 name show saleteam root@FB10Head:~ # ipfw table saleteam add 1.2.3.4 root@FB10Head:~ # ipfw table saleteam list 1.2.3.4/32 0 root@FB10Head:~ # ipfw table 1 list 1.2.3.4/32 0 root@FB10Head:~ # Currently still cleaning the table handling function, and did not add = the lock in the kernel functions when changing the `mapping chain`. Regards, bycn82 > -----Original Message----- > From: Alexander V. Chernikov [mailto:melifaro@ipfw.ru] > Sent: 05 June, 2014 18:22 > To: Luigi Rizzo > Cc: Luigi Rizzo; FreeBSD Net; Bill Yuan > Subject: Re: [CFT]: ipfw named tables / different tabletypes >=20 > On 01.06.2014 17:51, Alexander V. Chernikov wrote: > > On 22.05.2014 20:38, Luigi Rizzo wrote: > > > > Long story short, new version is ready. > > I've tried to minimize changes in this patch to ease review/commit. > > > > Changes: > > * Add namedobject set-aware api capable of searching/allocation > > objects by their name/idx. > > * Switch tables code to use string ids for configuration tasks. > > * Change locking model: most configuration changes are protected = with > > UH lock, runtime-visible are protected with both locks. > > * Reduce number of arguments passed to ipfw_table_add/del by using > > separate structure. > > * Add internal V_fw_tables_sets tunable (set to 0) to prepare for > > set-aware tables (requires opcodes/client support) > > * Implement typed table referencing (and tables are implicitly > > allocated with all state like radix ptrs on reference) > > * Add "destroy" ipfw(8) using new IP_FW_DELOBJ opcode > > > > Namedobj more detailed: > > * Blackbox api providing methods to add/del/search/enumerate objects > > * Statically-sized hashes for names/indexes > > * Per-set bitmask to indicate free indexes > > * Separate methods for index alloc/delete/resize > > > > > > Basically, there should not be any user-visible changes except the > > following: > > * reducing table_max is not supported > > * flush & add change table type won't work if table is referenced > > > > > > I haven't removed any numbering restrictions to protect the = following > > case: > > one (with old client) unintentionally references too many tables = (e.g. > > 1000-1128), > > tries to allocate table from "valid" range and fails. Old client = does > > not have any ability to destroy any table, so the only way to solve > > this is either module unload or reboot. > > > > I've uploaded the same patch to phabricator since it provides quite > > handy diffs: > > https://phabric.freebsd.org/D139 (no login required). > A bit cleaner version attached. > > > >> On Thu, May 22, 2014 at 08:09:55PM +0400, Alexander V. Chernikov > wrote: > >>> On 22.05.2014 19:47, Luigi Rizzo wrote: > >>>> On Thu, May 22, 2014 at 06:56:41PM +0400, Alexander V. Chernikov > >>>> wrote: > >>>>> On 22.05.2014 00:48, Luigi Rizzo wrote: > >>>>>> On Wed, May 21, 2014 at 10:10:26PM +0400, Alexander V. = Chernikov > >>>>>> wrote: > >>>> ... > >>>>>> we can solve this by using 'low' numbers for the numeric tables > >>>>>> (these were limited anyways) and allocate the fake entries in > >>>>>> another range. > >>>>> Currently we have u16 space available in base opcode. > >>>> yes but the standard range for tables is much more limited: > >>>> > >>>> net.inet.ip.fw.tables_max: 128 > >>>> > >>>> so one can just (say) use 32k for "old" tables and the rest for > >>>> tables with non numeric names. > >>>> Does not seem to be a problem in practice. > >>> Well, using upper 32k means that you set this default to 65k which > >>> consumes 256k of memory on 32-bit arch. > >>> Embedded people won't be very happy about this (and changing table > >>> numbers on resize would be a nightmare). > >> no no, this is an implementation detail but within the kernel you = can > >> just remap the 'old' and 'new' > >> table identifiers to a single contiguous range. > >> The only thing you need to do is that when you push identifiers up = to > >> userland, those with 'new' names will be mapped to the 32-64k = range. > >> > >> Example: > >> user first specifies tables > >> "18, goodguys, 530, badguys" in the same rule > >> /sbin/ipfw will generate these numbers: > >> 18, 32768, 530, 32769 ; tlv {32768:goodguys, 32769:badguys} > >> The kernel will then do a lookup of those identifiers and > >> 18: internal index 1, name "18" > >> 32768: internal index 2, name "goodguys" > >> 530: internal index 3, name "530" > >> 32769: internal index 4, name "badguys" > >> > >> Then the next rule contains tables > >> 1, badguys, 18 > >> /sbin/ipfw generates > >> 1, 32768, 18 ; tlv {32768:badguys} // note different from = before > >> Kernel looks up the names and remaps > >> 1: internal index 5, name "1" > >> 32768: internal index 4, name "badguys" > >> 18: internal index 1, name "18" > >> > >> Finally when you do an 'ipfw show' the kernel will remap names > >> between 1 and 32768 to themselves, and other names to 32768+ (or = some > >> other large number, say 40k and above) so as they are found. So the > >> rules will be pushed up with > >> 18, 40000, 530, 40001 > >> 1, 40001, 18 > >> > >> we can discusso the other details privately > >> > >> cheers > >> luigi > >> > >> > >> 1. first, the > >>>>>> maybe i am missing some detail but it seems reasonably easy to > >>>>>> implement the atomic swap -- and the use case is when you want = to > >>>>>> move from one configuration to a new one: > >>>>>> ipfw table foo-new flush // clear initial content > >>>>>> ipfw table foo-new add ... > >>>>>> ipfw table swap foo-current foo-new // swap the content of > >>>>>> the table objects > >>>>>> > >>>>>> so you preserve the semantic of the name very easily. > >>>>> Yes. We can easily add atomic table swap that way. However, I'm > >>>>> talking about different use scenario: > >>>>> Atomically swap entire ruleset which has some tables depency: > >>>>> > >>>>> > >>>>> e.g. we have: > >>>>> > >>>>> " > >>>>> 100 allow ip from table(TABLE1) to me > >>>>> 200 allow ip from table(TABLE2) to (TABLE3) 80 > >>>>> > >>>>> table TABLE1 1.1.1.1/32 > >>>>> table TABLE1 1.0.0.0/16 > >>>>> > >>>>> table TABLE2 2.2.2.2/32 > >>>>> > >>>>> table TABLE3 3.3.3.3/32 > >>>>> " > >>>>> and we want to _atomically_ change this to > >>>>> > >>>>> " > >>>>> 100 allow ip from table(TABLE1) to me > >>>>> +200 allow ip from table(TABLE4) to any > >>>>> 300 allow ip from table(TABLE2) to (TABLE3) 80 > >>>>> > >>>>> table TABLE1 1.1.1.1/32 > >>>>> -table TABLE1 1.0.0.0/16 > >>>>> > >>>>> -table TABLE2 2.2.2.2/32 > >>>>> +table TABLE2 77.77.77.0/24 > >>>>> > >>>>> table TABLE3 3.3.3.3/32 > >>>>> > >>>>> +table TABLE4 4.4.4.4/32 > >>>>> " > >>>> aargh, that's too much -- because between changing > >>>> one table and all tables there are infinite intermediate > >>>> points that all make sense. > >>> It depends. As I said before, we're currently solving this problem > by > >>> adding new rules (to set X) referencing tables from different = range > >>> (2048 tables per ruleset) and than doing swap. > >>> (And not being able to use named tables to store real names after > >>> implementing them is a bit discouraging). > >>> > >>>> For those cases i think the way to go could be to > >>>> insert a 'disabled' new ruleset (however complex it is, > >>>> so it covers all possible cases), and then do the set swap, > >>>> or disable/enable. > >>> We can think of per-set arrays/namespaces of tables: > >>> > >>> so "ipfw add 100 set X allow ipfw from table(Y) to ..." will > reference > >>> table Y in set X and > >>> "ipfw table ABC list" can differ from "ipfw table ABC set 5 list". > >>> > >>> This behavior can break some users setups so we can provide > >>> sysctl/tunable to turn this off or on. > >>> > >>>> cheers > >>>> luigi > >>>> > > ------=_NextPart_000_000D_01CF8101.4F3D6DD0 Content-Type: application/octet-stream; name="mapping.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="mapping.patch" Index: sbin/ipfw/ipfw2.c=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= --- sbin/ipfw/ipfw2.c (revision 267049)=0A= +++ sbin/ipfw/ipfw2.c (working copy)=0A= @@ -370,6 +370,17 @@=0A= { NULL, 0 } /* terminator */=0A= };=0A= =0A= +static struct _s_x table_actions[] =3D {=0A= + { "add", TOK_TBL_ADD },=0A= + { "delete", TOK_TBL_DEL },=0A= + { "del", TOK_TBL_DEL },=0A= + { "list", TOK_TBL_LIST },=0A= + { "flush", TOK_TBL_FLUSH },=0A= + { "name", TOK_TBL_NAME },=0A= + { "type", TOK_TBL_TYPE },=0A= + { NULL, 0 } /* terminator */=0A= +};=0A= +=0A= /*=0A= * Helper routine to print a possibly unaligned uint64_t on=0A= * various platform. If width > 0, print the value with=0A= @@ -4163,11 +4174,11 @@=0A= ipfw_table_handler(int ac, char *av[])=0A= {=0A= ipfw_table_xentry xent;=0A= - int do_add;=0A= int is_all;=0A= uint32_t a;=0A= uint32_t tables_max;=0A= =0A= +=0A= tables_max =3D ipfw_get_tables_max();=0A= =0A= memset(&xent, 0, sizeof(xent));=0A= @@ -4176,75 +4187,136 @@=0A= if (ac && isdigit(**av)) {=0A= xent.tbl =3D atoi(*av);=0A= is_all =3D 0;=0A= - ac--; av++;=0A= } else if (ac && _substrcmp(*av, "all") =3D=3D 0) {=0A= xent.tbl =3D 0;=0A= is_all =3D 1;=0A= - ac--; av++;=0A= - } else=0A= - errx(EX_USAGE, "table number or 'all' keyword required");=0A= - if (xent.tbl >=3D tables_max)=0A= - errx(EX_USAGE, "The table number exceeds the maximum allowed "=0A= - "value (%d)", tables_max - 1);=0A= + } else {=0A= + /* get table id via name and type*/=0A= + xent.tbl=3Dmapping_getid(IPFW_TABLE_NAME,*av);=0A= + is_all =3D 0;=0A= + }=0A= + ac--; av++;=0A= + if (xent.tbl >=3D tables_max){=0A= + errx(EX_USAGE, "The table number (%d) exceeds the maximum allowed "=0A= + "value (%d)",xent.tbl, tables_max - 1);=0A= + }=0A= NEED1("table needs command");=0A= - if (is_all && _substrcmp(*av, "list") !=3D 0=0A= - && _substrcmp(*av, "flush") !=3D 0)=0A= - errx(EX_USAGE, "table number required");=0A= -=0A= - if (_substrcmp(*av, "add") =3D=3D 0 ||=0A= - _substrcmp(*av, "delete") =3D=3D 0) {=0A= - do_add =3D **av =3D=3D 'a';=0A= - ac--; av++;=0A= - if (!ac)=0A= - errx(EX_USAGE, "address required");=0A= -=0A= - table_fill_xentry(*av, &xent);=0A= -=0A= - ac--; av++;=0A= - if (do_add && ac) {=0A= - unsigned int tval;=0A= - /* isdigit is a bit of a hack here.. */=0A= - if (strchr(*av, (int)'.') =3D=3D NULL && isdigit(**av)) {=0A= - xent.value =3D strtoul(*av, NULL, 0);=0A= - } else {=0A= - if (lookup_host(*av, (struct in_addr *)&tval) =3D=3D 0) {=0A= - /* The value must be stored in host order *=0A= - * so that the values < 65k can be distinguished */=0A= - xent.value =3D ntohl(tval);=0A= - } else {=0A= - errx(EX_NOHOST, "hostname ``%s'' unknown", *av);=0A= + int matched_index =3D match_token(table_actions, *av);=0A= + switch(matched_index) {=0A= + case TOK_TBL_ADD:=0A= + case TOK_TBL_DEL:=0A= + {=0A= + ac--; av++;=0A= + if (!ac){=0A= + errx(EX_USAGE, "address required");=0A= }=0A= + table_fill_xentry(*av, &xent);=0A= + ac--; av++;=0A= + if (matched_index=3D=3DTOK_TBL_ADD && ac) {=0A= + unsigned int tval;=0A= + /* isdigit is a bit of a hack here.. */=0A= + if (strchr(*av, (int)'.') =3D=3D NULL && isdigit(**av)) {=0A= + xent.value =3D strtoul(*av, NULL, 0);=0A= + } else {=0A= + if (lookup_host(*av, (struct in_addr *)&tval) =3D=3D 0) {=0A= + /* The value must be stored in host order *=0A= + * so that the values < 65k can be distinguished */=0A= + xent.value =3D ntohl(tval);=0A= + } else {=0A= + errx(EX_NOHOST, "hostname ``%s'' unknown", *av);=0A= + }=0A= + }=0A= + } else{=0A= + xent.value =3D 0;=0A= + }=0A= + if (do_setcmd3(matched_index=3D=3DTOK_TBL_ADD ? IP_FW_TABLE_XADD : = IP_FW_TABLE_XDEL,=0A= + &xent, xent.len) < 0) {=0A= + /* If running silent, don't bomb out on these errors. */=0A= + if (!(co.do_quiet && (errno =3D=3D (matched_index=3D=3DTOK_TBL_ADD = ? EEXIST : ESRCH))))=0A= + err(EX_OSERR, "setsockopt(IP_FW_TABLE_%s)",=0A= + matched_index=3D=3DTOK_TBL_ADD ? "XADD" : "XDEL");=0A= + /* In silent mode, react to a failed add by deleting */=0A= + if (matched_index=3D=3DTOK_TBL_ADD) {=0A= + do_setcmd3(IP_FW_TABLE_XDEL, &xent, xent.len);=0A= + if (do_setcmd3(IP_FW_TABLE_XADD, &xent, xent.len) < 0)=0A= + err(EX_OSERR,=0A= + "setsockopt(IP_FW_TABLE_XADD)");=0A= + }=0A= + }=0A= }=0A= - } else=0A= - xent.value =3D 0;=0A= - if (do_setcmd3(do_add ? IP_FW_TABLE_XADD : IP_FW_TABLE_XDEL,=0A= - &xent, xent.len) < 0) {=0A= - /* If running silent, don't bomb out on these errors. */=0A= - if (!(co.do_quiet && (errno =3D=3D (do_add ? EEXIST : ESRCH))))=0A= - err(EX_OSERR, "setsockopt(IP_FW_TABLE_%s)",=0A= - do_add ? "XADD" : "XDEL");=0A= - /* In silent mode, react to a failed add by deleting */=0A= - if (do_add) {=0A= - do_setcmd3(IP_FW_TABLE_XDEL, &xent, xent.len);=0A= - if (do_setcmd3(IP_FW_TABLE_XADD, &xent, xent.len) < 0)=0A= - err(EX_OSERR,=0A= - "setsockopt(IP_FW_TABLE_XADD)");=0A= + break;=0A= + case TOK_TBL_FLUSH:=0A= + {=0A= + a =3D is_all ? tables_max : (uint32_t)(xent.tbl + 1);=0A= + do {=0A= + if (do_cmd(IP_FW_TABLE_FLUSH, &xent.tbl,=0A= + sizeof(xent.tbl)) < 0)=0A= + err(EX_OSERR, "setsockopt(IP_FW_TABLE_FLUSH)");=0A= + } while (++xent.tbl < a);=0A= }=0A= - }=0A= - } else if (_substrcmp(*av, "flush") =3D=3D 0) {=0A= - a =3D is_all ? tables_max : (uint32_t)(xent.tbl + 1);=0A= - do {=0A= - if (do_cmd(IP_FW_TABLE_FLUSH, &xent.tbl,=0A= - sizeof(xent.tbl)) < 0)=0A= - err(EX_OSERR, "setsockopt(IP_FW_TABLE_FLUSH)");=0A= - } while (++xent.tbl < a);=0A= - } else if (_substrcmp(*av, "list") =3D=3D 0) {=0A= - a =3D is_all ? tables_max : (uint32_t)(xent.tbl + 1);=0A= - do {=0A= - table_list(xent.tbl, is_all);=0A= - } while (++xent.tbl < a);=0A= - } else=0A= - errx(EX_USAGE, "invalid table command %s", *av);=0A= + break;=0A= + case TOK_TBL_LIST:=0A= + {=0A= + a =3D is_all ? tables_max : (uint32_t)(xent.tbl + 1);=0A= + do {=0A= + table_list(xent.tbl, is_all);=0A= + } while (++xent.tbl < a);=0A= + }=0A= + break;=0A= + case TOK_TBL_NAME:=0A= + case TOK_TBL_TYPE:=0A= + {=0A= + if (ac=3D=3D1){=0A= + errx(EX_USAGE, "more option required");=0A= + }=0A= + =0A= + int type;=0A= + if(matched_index=3D=3DTOK_TBL_NAME){=0A= + type=3DIPFW_TABLE_NAME;=0A= + }else if(matched_index=3D=3DTOK_TBL_TYPE){=0A= + type=3DIPFW_TABLE_TYPE;=0A= + }=0A= + av++;=0A= + if (_substrcmp(*av, "delete") =3D=3D 0){=0A= + ipfw_mapping mapping_element;=0A= + memset(&mapping_element, 0, sizeof(mapping_element));=0A= + mapping_element.id=3Dxent.tbl;=0A= + mapping_element.type=3Dtype;=0A= + if (do_setcmd3(IP_FW_MAPPING_DEL,&mapping_element,=0A= + sizeof(mapping_element)) < 0){=0A= + err(EX_OSERR,"setsockopt(IP_FW_MAPPING_SET)");=0A= + }=0A= + }else if (_substrcmp(*av, "show") =3D=3D 0){=0A= + ip_fw3_opheader *op3;=0A= + socklen_t len;=0A= + len =3D sizeof(ip_fw3_opheader) + sizeof(ipfw_mapping);=0A= + op3 =3D alloca(len);=0A= + memset(op3, 0, sizeof(ip_fw3_opheader));=0A= + ipfw_mapping *mapping=3D(ipfw_mapping *)(op3+1);=0A= + mapping->id=3Dxent.tbl;=0A= + mapping->type=3Dtype;=0A= + op3->opcode =3D IP_FW_MAPPING_GET;=0A= + if (do_cmd(IP_FW3, op3, (uintptr_t)&len) < 0){=0A= + err(EX_OSERR, "getsockopt(IP_FW_TABLE_XGETSIZE)");=0A= + }=0A= + printf("%s\n",mapping->label);=0A= + }else{=0A= + ipfw_mapping mapping_element;=0A= + memset(&mapping_element, 0, sizeof(mapping_element));=0A= + mapping_element.id=3Dxent.tbl;=0A= + mapping_element.type=3Dtype;=0A= + strcpy(mapping_element.label,*av);=0A= + if (do_setcmd3(IP_FW_MAPPING_SET,&mapping_element,=0A= + sizeof(mapping_element)) < 0){=0A= + err(EX_OSERR,"setsockopt(IP_FW_MAPPING_SET)");=0A= + }=0A= + }=0A= +=0A= + }=0A= + break;=0A= + default:=0A= + errx(EX_USAGE, "invalid table command %s", *av);=0A= + }=0A= }=0A= =0A= static void=0A= @@ -4423,3 +4495,20 @@=0A= =0A= free(tbl);=0A= }=0A= +int mapping_getid(int type,char *label){=0A= + ip_fw3_opheader *op3;=0A= + socklen_t len;=0A= + len =3D sizeof(ip_fw3_opheader) + sizeof(ipfw_mapping);=0A= + op3 =3D alloca(len);=0A= + memset(op3, 0, sizeof(ip_fw3_opheader));=0A= + ipfw_mapping *mapping=3D(ipfw_mapping *)(op3+1);=0A= +=0A= + mapping->type=3Dtype;=0A= + mapping->id=3D0;=0A= + strcpy(mapping->label,label);=0A= + op3->opcode =3D IP_FW_MAPPING_GET;=0A= + if (do_cmd(IP_FW3, op3, (uintptr_t)&len) < 0){=0A= + err(EX_OSERR, "getsockopt(IP_FW_TABLE_XGETSIZE)");=0A= + }=0A= + return mapping->id;=0A= +}=0A= Index: sbin/ipfw/ipfw2.h=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= --- sbin/ipfw/ipfw2.h (revision 267049)=0A= +++ sbin/ipfw/ipfw2.h (working copy)=0A= @@ -205,6 +205,13 @@=0A= TOK_LOOKUP,=0A= TOK_SOCKARG,=0A= TOK_SETDSCP,=0A= + /* table tokens */=0A= + TOK_TBL_ADD,=0A= + TOK_TBL_DEL,=0A= + TOK_TBL_LIST,=0A= + TOK_TBL_FLUSH,=0A= + TOK_TBL_NAME,=0A= + TOK_TBL_TYPE,=0A= };=0A= /*=0A= * the following macro returns an error message if we run out of=0A= @@ -297,3 +304,9 @@=0A= void fill_unreach6_code(u_short *codep, char *str);=0A= void fill_icmp6types(struct _ipfw_insn_icmp6 *cmd, char *av, int cblen);=0A= int fill_ext6hdr(struct _ipfw_insn *cmd, char *av);=0A= +=0A= +/* table mapping */=0A= +int mapping_getid(int type,char *label);=0A= +void mapping_getlabel(int id,int type,char *label);=0A= +void mapping_add(int id,int type,char *label);=0A= +void mapping_delete(int id,int type);=0A= Index: sys/modules/ipfw/Makefile=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= --- sys/modules/ipfw/Makefile (revision 267049)=0A= +++ sys/modules/ipfw/Makefile (working copy)=0A= @@ -17,7 +17,7 @@=0A= #CFLAGS+=3D -DIPFIREWALL_VERBOSE_LIMIT=3D100=0A= #=0A= #If you want it to pass all packets by default=0A= -#CFLAGS+=3D -DIPFIREWALL_DEFAULT_TO_ACCEPT=0A= +CFLAGS+=3D -DIPFIREWALL_DEFAULT_TO_ACCEPT=0A= #=0A= =0A= .if !defined(KERNBUILDDIR)=0A= Index: sys/netinet/ip_fw.h=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= --- sys/netinet/ip_fw.h (revision 267049)=0A= +++ sys/netinet/ip_fw.h (working copy)=0A= @@ -75,6 +75,10 @@=0A= #define IP_FW_TABLE_XGETSIZE 88 /* get table size */=0A= #define IP_FW_TABLE_XLIST 89 /* list table contents */=0A= =0A= +#define IP_FW_MAPPING_GET 90=0A= +#define IP_FW_MAPPING_SET 91=0A= +#define IP_FW_MAPPING_DEL 92=0A= +=0A= /*=0A= * The kernel representation of ipfw rules is made of a list of=0A= * 'instructions' (for all practical purposes equivalent to BPF=0A= @@ -602,6 +606,11 @@=0A= #define IPFW_TABLE_INTERFACE 2 /* Table for holding interface names */=0A= #define IPFW_TABLE_MAXTYPE 2 /* Maximum valid number */=0A= =0A= +#define IPFW_TABLE_NAME 1 /* type in mapping */=0A= +#define IPFW_TABLE_TYPE 2 /* type in mapping */=0A= +#define IPFW_PIPE_NAME 3 /* type in mapping */=0A= +#define IPFW_QUEUE_NAME 4 /* type in mapping */=0A= +=0A= typedef struct _ipfw_table_entry {=0A= in_addr_t addr; /* network address */=0A= u_int32_t value; /* value */=0A= @@ -624,6 +633,18 @@=0A= } ipfw_table_xentry;=0A= #define IPFW_TCF_INET 0x01 /* CIDR flags: IPv4 record */=0A= =0A= +typedef struct _ipfw_mapping{=0A= + uint16_t id;=0A= + uint8_t type;=0A= + char label[20];=0A= + struct _ipfw_mapping *next;=0A= +} ipfw_mapping;=0A= +=0A= +typedef struct _ipfw_mapping_query{=0A= + ip_fw3_opheader opheader;=0A= + ipfw_mapping mapping;=0A= +} ipfw_mapping_query;=0A= +=0A= typedef struct _ipfw_table {=0A= u_int32_t size; /* size of entries in bytes */=0A= u_int32_t cnt; /* # of entries */=0A= Index: sys/netpfil/ipfw/ip_fw_private.h=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= --- sys/netpfil/ipfw/ip_fw_private.h (revision 267049)=0A= +++ sys/netpfil/ipfw/ip_fw_private.h (working copy)=0A= @@ -233,6 +233,7 @@=0A= spinlock_t uh_lock;=0A= #else=0A= struct rwlock uh_lock; /* lock for upper half */=0A= + struct _ipfw_mapping *mapping;=0A= #endif=0A= };=0A= =0A= Index: sys/netpfil/ipfw/ip_fw_sockopt.c=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= --- sys/netpfil/ipfw/ip_fw_sockopt.c (revision 267049)=0A= +++ sys/netpfil/ipfw/ip_fw_sockopt.c (working copy)=0A= @@ -1280,7 +1280,116 @@=0A= free(tbl, M_TEMP);=0A= }=0A= break;=0A= -=0A= + /* MAPPING */=0A= + case IP_FW_MAPPING_SET:=0A= + {=0A= + ipfw_mapping *ele=3D (ipfw_mapping *)(op3 + 1);=0A= + ipfw_mapping *current_ele,*new_ele;=0A= + int found=3D0,current_need_checked=3D1;=0A= + if ((size =3D valsize) < sizeof(ipfw_mapping)) {=0A= + error =3D EINVAL;=0A= + break;=0A= + }=0A= + new_ele=3D malloc(size, M_TEMP, M_ZERO | M_WAITOK);=0A= + memcpy(new_ele, ele, sizeof(ipfw_mapping));=0A= + current_ele=3Dchain->mapping;=0A= + if(current_ele!=3DNULL){=0A= + while(current_need_checked=3D=3D1)=0A= + {=0A= + if(ele->id=3D=3Dcurrent_ele->id && ele->type=3D=3D = current_ele->type){=0A= + found=3D1;=0A= + break;=0A= + }=0A= + current_need_checked=3D0; =0A= + /* if current is the last element, then just quit the loop.*/=0A= + if(current_ele->next!=3DNULL){=0A= + current_ele=3Dcurrent_ele->next;=0A= + current_need_checked=3D1;=0A= + }=0A= + }=0A= + /* if found, then update the label, otherwise, append to the last = element, */=0A= + if(found){=0A= + strcpy(current_ele->label,ele->label);=0A= + }else{=0A= + current_ele->next=3Dnew_ele;=0A= + }=0A= + }else{=0A= + /* append the new_element into the chain */=0A= + chain->mapping=3Dnew_ele;=0A= + }=0A= + }=0A= + break;=0A= + case IP_FW_MAPPING_GET:=0A= + {=0A= + ipfw_mapping *ele=3D (ipfw_mapping *)(op3 + 1);=0A= + ipfw_mapping *current_ele;=0A= + int found=3D0,current_need_checked=3D1;=0A= + current_ele=3Dchain->mapping;=0A= + if(current_ele!=3DNULL){=0A= + while(current_need_checked=3D=3D1)=0A= + {=0A= + if(ele->id=3D=3D0){=0A= + if(ele->type=3D=3D current_ele->type && = strcmp(ele->label,current_ele->label)=3D=3D0){=0A= + found=3D1;=0A= + break;=0A= + }=0A= + }else{=0A= + if(ele->id=3D=3Dcurrent_ele->id && ele->type=3D=3D = current_ele->type){=0A= + found=3D1;=0A= + break;=0A= + }=0A= + }=0A= + current_need_checked=3D0; =0A= + if(current_ele->next!=3DNULL){=0A= + current_ele=3Dcurrent_ele->next;=0A= + current_need_checked=3D1; =0A= + }=0A= + }=0A= + /* if found, copy out*/=0A= + if(found){=0A= + if(ele->id=3D=3D0){=0A= + ele->id=3Dcurrent_ele->id;=0A= + }else{=0A= + strcpy(ele->label,current_ele->label);=0A= + }=0A= + error =3D sooptcopyout(sopt, op3, sizeof(ipfw_mapping_query));=0A= + }=0A= + }else{=0A= + error =3D EINVAL;=0A= + }=0A= + }=0A= + break;=0A= + case IP_FW_MAPPING_DEL:=0A= + {=0A= + ipfw_mapping *ele=3D (ipfw_mapping *)(op3 + 1);=0A= + ipfw_mapping *previous_ele,*current_ele,*next_ele;=0A= + current_ele=3Dchain->mapping;=0A= + if(current_ele!=3DNULL){=0A= + /* if delete the first element */=0A= + if(ele->id=3D=3Dcurrent_ele->id && ele->type=3D=3D = current_ele->type){=0A= + next_ele=3Dcurrent_ele->next;=0A= + if(next_ele!=3DNULL){=0A= + chain->mapping=3Dnext_ele;=0A= + }=0A= + free(current_ele,M_TEMP);=0A= + }else{=0A= + next_ele=3Dcurrent_ele->next;=0A= + while(next_ele!=3DNULL){=0A= + previous_ele=3Dcurrent_ele;=0A= + current_ele=3Dcurrent_ele->next;=0A= + next_ele=3Dcurrent_ele->next;=0A= + if(ele->id=3D=3Dcurrent_ele->id && ele->type=3D=3D = current_ele->type){=0A= + free(current_ele,M_TEMP);=0A= + break;=0A= + }=0A= + previous_ele->next=3Dnext_ele;=0A= + }=0A= + }=0A= + }else{=0A= + error =3D EINVAL;=0A= + }=0A= + }=0A= + break;=0A= /*--- NAT operations are protected by the IPFW_LOCK ---*/=0A= case IP_FW_NAT_CFG:=0A= if (IPFW_NAT_LOADED)=0A= ------=_NextPart_000_000D_01CF8101.4F3D6DD0--