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