Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 5 Jun 2014 21:01:19 +0800
From:      "bycn82" <bycn82@gmail.com>
To:        "'Alexander V. Chernikov'" <melifaro@ipfw.ru>
Cc:        'Luigi Rizzo' <luigi@FreeBSD.org>, 'FreeBSD Net' <net@FreeBSD.org>
Subject:   RE: [CFT]: ipfw named tables / different tabletypes
Message-ID:  <000c01cf80be$41194370$c34bca50$@gmail.com>
In-Reply-To: <539044E4.1020904@ipfw.ru>
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>

next in thread | previous in thread | raw e-mail | index | archive | help
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  ... <repeat as needed>
> >>>>>>     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--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?000c01cf80be$41194370$c34bca50$>