svn commit: r269988 - in projects/ipfw: sbin/ipfw sys/netpfil/ipfw

Alexander V. Chernikov melifaro at FreeBSD.org
Thu Aug 14 17:31:06 UTC 2014


Author: melifaro
Date: Thu Aug 14 17:31:04 2014
New Revision: 269988
URL: http://svnweb.freebsd.org/changeset/base/269988

Log:
  * Document internal commands.
  * Do not require/set default table type if algo name is specified.
  * Add TA_FLAG_READONLY option for algorithms.

Modified:
  projects/ipfw/sbin/ipfw/ipfw.8
  projects/ipfw/sbin/ipfw/tables.c
  projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c
  projects/ipfw/sys/netpfil/ipfw/ip_fw_table.h
  projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c

Modified: projects/ipfw/sbin/ipfw/ipfw.8
==============================================================================
--- projects/ipfw/sbin/ipfw/ipfw.8	Thu Aug 14 16:45:02 2014	(r269987)
+++ projects/ipfw/sbin/ipfw/ipfw.8	Thu Aug 14 17:31:04 2014	(r269988)
@@ -113,6 +113,11 @@ in-kernel NAT.
 .Oc
 .Oc
 .Ar pathname
+.Ss INTERNAL DIAGNOSTICS
+.Nm
+.Cm internal iflist
+.Nm
+.Cm internal talist
 .Sh DESCRIPTION
 The
 .Nm
@@ -3181,6 +3186,22 @@ Controls whether bridged packets are pas
 .Nm .
 Default is no.
 .El
+.Sh INTERNAL DIAGNOSTICS
+There are some commands that may be useful to understand current state
+of certain subsystems inside kernel module.
+These commands provide debugging output which may change without notice.
+.Pp
+Currently the following commands are available as
+.Cm internal
+sub-options:
+.Bl -tag -width indent
+.It Cm iflist
+Lists all interface which are currently tracked by
+.Nm
+with their in-kernel status.
+.It Cm talist
+List all table lookup algorithms currently available.
+.El
 .Sh EXAMPLES
 There are far too many possible uses of
 .Nm

Modified: projects/ipfw/sbin/ipfw/tables.c
==============================================================================
--- projects/ipfw/sbin/ipfw/tables.c	Thu Aug 14 16:45:02 2014	(r269987)
+++ projects/ipfw/sbin/ipfw/tables.c	Thu Aug 14 17:31:04 2014	(r269988)
@@ -391,10 +391,6 @@ table_create(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) {
 		tcmd = get_token(tablenewcmds, *av, "option");
 		ac--; av++;
@@ -464,6 +460,12 @@ table_create(ipfw_obj_header *oh, int ac
 		}
 	}
 
+	/* Set some defaults to preserve compability */
+	if (xi.algoname[0] == '\0' && xi.type == 0)
+		xi.type = IPFW_TABLE_CIDR;
+	if (xi.vtype == 0)
+		xi.vtype = IPFW_VTYPE_U32;
+
 	if ((error = table_do_create(oh, &xi)) != 0)
 		err(EX_OSERR, "Table creation failed");
 }

Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c	Thu Aug 14 16:45:02 2014	(r269987)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c	Thu Aug 14 17:31:04 2014	(r269988)
@@ -667,6 +667,9 @@ check_table_space(struct ip_fw_chain *ch
 
 	error = 0;
 	ta = tc->ta;
+	if (ta->need_modify == NULL)
+		return (0);
+
 	/* Acquire reference not to loose @tc between locks/unlocks */
 	tc->no.refcnt++;
 
@@ -1051,6 +1054,11 @@ flush_table(struct ip_fw_chain *ch, stru
 		return (ESRCH);
 	}
 	ta = tc->ta;
+	/* Do not flush readonly tables */
+	if ((ta->flags & TA_FLAG_READONLY) != 0) {
+		IPFW_UH_WUNLOCK(ch);
+		return (EACCES);
+	}
 	tc->no.refcnt++;
 	/* Save startup algo parameters */
 	if (ta->print_config != NULL) {
@@ -1206,6 +1214,12 @@ swap_tables(struct ip_fw_chain *ch, stru
 		return (EFBIG);
 	}
 
+	/* Check if one of the tables is readonly */
+	if (((tc_a->ta->flags | tc_b->ta->flags) & TA_FLAG_READONLY) != 0) {
+		IPFW_UH_WUNLOCK(ch);
+		return (EACCES);
+	}
+
 	/* Everything is fine, prepare to swap */
 	tablestate = (struct table_info *)ch->tablestate;
 	ti = tablestate[tc_a->no.kidx];
@@ -1622,6 +1636,13 @@ ipfw_modify_table(struct ip_fw_chain *ch
 		IPFW_UH_WUNLOCK(ch);
 		return (ESRCH);
 	}
+
+	/* Do not support any modifications for readonly tables */
+	if ((tc->ta->flags & TA_FLAG_READONLY) != 0) {
+		IPFW_UH_WUNLOCK(ch);
+		return (EACCES);
+	}
+
 	if ((i->mflags & IPFW_TMFLAGS_FTYPE) != 0)
 		tc->vftype = i->vftype;
 	if ((i->mflags & IPFW_TMFLAGS_LIMIT) != 0)
@@ -1720,7 +1741,10 @@ create_table_internal(struct ip_fw_chain
 
 	tc->vftype = i->vftype;
 	tc->limit = i->limit;
-	tc->locked = (i->flags & IPFW_TGFLAGS_LOCKED) != 0;
+	if (ta->flags & TA_FLAG_READONLY)
+		tc->locked = 1;
+	else
+		tc->locked = (i->flags & IPFW_TGFLAGS_LOCKED) != 0;
 
 	IPFW_UH_WLOCK(ch);
 
@@ -2311,32 +2335,36 @@ find_table_algo(struct tables_config *tc
 		return (tcfg->algo[ti->atype]);
 	}
 
-	/* Search by name if supplied */
-	if (name != NULL) {
-		/* TODO: better search */
-		for (i = 1; i <= tcfg->algo_count; i++) {
-			ta = tcfg->algo[i];
+	if (name == NULL) {
+		/* Return default algorithm for given type if set */
+		return (tcfg->def_algo[ti->type]);
+	}
 
-			/*
-			 * One can supply additional algorithm
-			 * parameters so we compare only the first word
-			 * of supplied name:
-			 * 'hash_cidr hsize=32'
-			 * '^^^^^^^^^'
-			 *
-			 */
-			l = strlen(ta->name);
-			if (strncmp(name, ta->name, l) == 0) {
-				if (name[l] == '\0' || name[l] == ' ')
-					return (ta);
-			}
-		}
+	/* Search by name */
+	/* TODO: better search */
+	for (i = 1; i <= tcfg->algo_count; i++) {
+		ta = tcfg->algo[i];
 
-		return (NULL);
+		/*
+		 * One can supply additional algorithm
+		 * parameters so we compare only the first word
+		 * of supplied name:
+		 * 'hash_cidr hsize=32'
+		 * '^^^^^^^^^'
+		 *
+		 */
+		l = strlen(ta->name);
+		if (strncmp(name, ta->name, l) != 0)
+			continue;
+		if (name[l] != '\0' && name[l] != ' ')
+			continue;
+		/* Check if we're requesting proper table type */
+		if (ti->type != 0 && ti->type != ta->type)
+			return (NULL);
+		return (ta);
 	}
 
-	/* Return default algorithm for given type if set */
-	return (tcfg->def_algo[ti->type]);
+	return (NULL);
 }
 
 /*
@@ -2704,7 +2732,7 @@ alloc_table_config(struct ip_fw_chain *c
 
 	tc = malloc(sizeof(struct table_config), M_IPFW, M_WAITOK | M_ZERO);
 	tc->no.name = tc->tablename;
-	tc->no.type = ti->type;
+	tc->no.type = ta->type;
 	tc->no.set = set;
 	tc->tflags = tflags;
 	tc->ta = ta;

Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table.h
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_table.h	Thu Aug 14 16:45:02 2014	(r269987)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table.h	Thu Aug 14 17:31:04 2014	(r269988)
@@ -132,7 +132,8 @@ struct table_algo {
 	ta_print_config	*print_config;
 	ta_dump_tinfo	*dump_tinfo;
 };
-#define	TA_FLAG_DEFAULT	0x01	/* Algorithm is default for given type */
+#define	TA_FLAG_DEFAULT		0x01	/* Algo is default for given type */
+#define	TA_FLAG_READONLY	0x02	/* Algo does not support modifications*/
 
 int ipfw_add_table_algo(struct ip_fw_chain *ch, struct table_algo *ta,
     size_t size, int *idx);

Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c	Thu Aug 14 16:45:02 2014	(r269987)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c	Thu Aug 14 17:31:04 2014	(r269988)
@@ -179,7 +179,7 @@ __FBSDID("$FreeBSD: projects/ipfw/sys/ne
  * -need_modify: checks if @ti has enough space to hold another @count items.
  *  typedef int (ta_need_modify)(void *ta_state, struct table_info *ti,
  *      uint32_t count, uint64_t *pflags);
- *  MANDATORY, locked (UH). (M_NOWAIT). Returns 0 if has.
+ *  OPTIONAL, locked (UH). (M_NOWAIT). Returns 0 if has.
  *
  *  Checks if given table has enough space to add @count items without
  *  resize. Caller may use @pflags to store desired modification data.
@@ -188,7 +188,7 @@ __FBSDID("$FreeBSD: projects/ipfw/sys/ne
  *
  * -prepare_mod: allocate structures for table modification.
  *  typedef int (ta_prepare_mod)(void *ta_buf, uint64_t *pflags);
- * MANDATORY, unlocked. (M_WAITOK). Returns 0 on success.
+ * OPTIONAL(need_modify), unlocked. (M_WAITOK). Returns 0 on success.
  *
  * Allocate all needed state for table modification. Caller
  * should use `struct mod_item` to store new state in @ta_buf.
@@ -199,7 +199,7 @@ __FBSDID("$FreeBSD: projects/ipfw/sys/ne
  * -fill_mod: copy some data to new state/
  *  typedef int (ta_fill_mod)(void *ta_state, struct table_info *ti,
  *      void *ta_buf, uint64_t *pflags);
- * MANDATORY, locked (UH). (M_NOWAIT). Returns 0 on success.
+ * OPTIONAL(need_modify), locked (UH). (M_NOWAIT). Returns 0 on success.
  *
  * Copy as much data as we can to minimize changes under WLOCK.
  * For example, array can be merged inside this callback.
@@ -209,7 +209,7 @@ __FBSDID("$FreeBSD: projects/ipfw/sys/ne
  * -modify: perform final modification.
  *  typedef void (ta_modify)(void *ta_state, struct table_info *ti,
  *      void *ta_buf, uint64_t pflags);
- * MANDATORY, locked (UH+WLOCK). (M_NOWAIT). 
+ * OPTIONAL(need_modify), locked (UH+WLOCK). (M_NOWAIT). 
  *
  * Performs all changes necessary to switch to new structures.
  * * Caller should save old pointers to @ta_buf storage.
@@ -218,7 +218,7 @@ __FBSDID("$FreeBSD: projects/ipfw/sys/ne
  *
  * -flush_mod: flush table modification state.
  *  typedef void (ta_flush_mod)(void *ta_buf);
- * MANDATORY, unlocked. (M_WAITOK).
+ * OPTIONAL(need_modify), unlocked. (M_WAITOK).
  *
  * Performs flush for the following:
  *   - prepare_mod (modification was not necessary)


More information about the svn-src-projects mailing list