svn commit: r272745 - in projects/ipfw/sys: netinet netpfil/ipfw

Alexander V. Chernikov melifaro at FreeBSD.org
Wed Oct 8 11:12:16 UTC 2014


Author: melifaro
Date: Wed Oct  8 11:12:14 2014
New Revision: 272745
URL: https://svnweb.freebsd.org/changeset/base/272745

Log:
  Add IP_FW_DUMP_SOPTCODES sopt to be able to determine
  which opcodes are currently available in kernel.

Modified:
  projects/ipfw/sys/netinet/ip_fw.h
  projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c
  projects/ipfw/sys/netpfil/ipfw/ip_fw_table_value.c

Modified: projects/ipfw/sys/netinet/ip_fw.h
==============================================================================
--- projects/ipfw/sys/netinet/ip_fw.h	Wed Oct  8 10:14:37 2014	(r272744)
+++ projects/ipfw/sys/netinet/ip_fw.h	Wed Oct  8 11:12:14 2014	(r272745)
@@ -104,6 +104,8 @@ typedef struct _ip_fw3_opheader {
 #define	IP_FW_NAT44_LIST_NAT	114	/* List all NAT44 instances */
 #define	IP_FW_NAT44_XGETLOG	115	/* Get log from NAT44 instance */
 
+#define	IP_FW_DUMP_SOPTCODES	116	/* Dump available sopts/versions */
+
 /*
  * The kernel representation of ipfw rules is made of a list of
  * 'instructions' (for all practical purposes equivalent to BPF
@@ -991,4 +993,12 @@ typedef struct _ipfw_range_header {
 	ipfw_range_tlv	range;
 } ipfw_range_header;
 
+typedef struct _ipfw_sopt_info {
+	uint16_t	opcode;
+	uint8_t		version;
+	uint8_t		dir;
+	uint8_t		spare;
+	uint64_t	refcnt;
+} ipfw_sopt_info;
+
 #endif /* _IPFW2_H */

Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c	Wed Oct  8 10:14:37 2014	(r272744)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c	Wed Oct  8 11:12:14 2014	(r272745)
@@ -115,6 +115,8 @@ static int move_rules(struct ip_fw_chain
     struct sockopt_data *sd);
 static int manage_sets(struct ip_fw_chain *chain, ip_fw3_opheader *op3,
     struct sockopt_data *sd);
+static int dump_soptcodes(struct ip_fw_chain *chain, ip_fw3_opheader *op3,
+    struct sockopt_data *sd);
 
 /* ctl3 handler data */
 struct mtx ctl3_lock;
@@ -141,6 +143,7 @@ static struct ipfw_sopt_handler	scodes[]
 	{ IP_FW_SET_SWAP,	0,	HDIR_SET,	manage_sets },
 	{ IP_FW_SET_MOVE,	0,	HDIR_SET,	manage_sets },
 	{ IP_FW_SET_ENABLE,	0,	HDIR_SET,	manage_sets },
+	{ IP_FW_DUMP_SOPTCODES,	0,	HDIR_GET,	dump_soptcodes },
 };
 
 /*
@@ -2285,6 +2288,57 @@ add_rules(struct ip_fw_chain *chain, ip_
 }
 
 /*
+ * Lists all sopts currently registered.
+ * Data layout (v0)(current):
+ * Request: [ ipfw_obj_lheader ], size = ipfw_obj_lheader.size
+ * Reply: [ ipfw_obj_lheader ipfw_sopt_info x N ]
+ *
+ * Returns 0 on success
+ */
+static int
+dump_soptcodes(struct ip_fw_chain *chain, ip_fw3_opheader *op3,
+    struct sockopt_data *sd)
+{
+	struct _ipfw_obj_lheader *olh;
+	ipfw_sopt_info *i;
+	struct ipfw_sopt_handler *sh;
+	uint32_t count, n, size;
+
+	olh = (struct _ipfw_obj_lheader *)ipfw_get_sopt_header(sd,sizeof(*olh));
+	if (olh == NULL)
+		return (EINVAL);
+	if (sd->valsize < olh->size)
+		return (EINVAL);
+
+	CTL3_LOCK();
+	count = ctl3_hsize;
+	size = count * sizeof(ipfw_sopt_info) + sizeof(ipfw_obj_lheader);
+
+	/* Fill in header regadless of buffer size */
+	olh->count = count;
+	olh->objsize = sizeof(ipfw_sopt_info);
+
+	if (size > olh->size) {
+		olh->size = size;
+		CTL3_UNLOCK();
+		return (ENOMEM);
+	}
+	olh->size = size;
+
+	for (n = 1; n <= count; n++) {
+		i = (ipfw_sopt_info *)ipfw_get_sopt_space(sd, sizeof(*i));
+		KASSERT(i != 0, ("previously checked buffer is not enough"));
+		sh = &ctl3_handlers[n];
+		i->opcode = sh->opcode;
+		i->version = sh->version;
+		i->refcnt = sh->refcnt;
+	}
+	CTL3_UNLOCK();
+
+	return (0);
+}
+
+/*
  * Compares two sopt handlers (code, version and handler ptr).
  * Used both as qsort() and bsearch().
  * Does not compare handler for latter case.

Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table_value.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_table_value.c	Wed Oct  8 10:14:37 2014	(r272744)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table_value.c	Wed Oct  8 11:12:14 2014	(r272745)
@@ -547,8 +547,15 @@ ipfw_link_table_values(struct ip_fw_chai
 	IPFW_UH_WLOCK(ch);
 	tc_unref(tc);
 	del_toperation_state(ch, ts);
-	if (ts->modified != 0)
+	if (ts->modified != 0) {
+
+		/*
+		 * In general, we should free all state/indexes here
+		 * and return. However, we keep allocated state instead
+		 * to ensure we achieve some progress on each restart.
+		 */
 		return (0);
+	}
 
 	KASSERT(pval == ch->tablestate, ("resize_storage() notify failure"));
 


More information about the svn-src-projects mailing list