svn commit: r282004 - head/sbin/ipfw

Alexander V. Chernikov melifaro at FreeBSD.org
Sun Apr 26 10:53:37 UTC 2015


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;


More information about the svn-src-head mailing list