svn commit: r290330 - in head: sbin/ipfw sys/netinet sys/netpfil/ipfw

Andrey V. Elsukov ae at FreeBSD.org
Tue Nov 3 10:21:55 UTC 2015


Author: ae
Date: Tue Nov  3 10:21:53 2015
New Revision: 290330
URL: https://svnweb.freebsd.org/changeset/base/290330

Log:
  Implement `ipfw internal olist` command to list named objects.
  
  Reviewed by:	melifaro
  Obtained from:	Yandex LLC
  Sponsored by:	Yandex LLC

Modified:
  head/sbin/ipfw/ipfw2.c
  head/sbin/ipfw/ipfw2.h
  head/sys/netinet/ip_fw.h
  head/sys/netpfil/ipfw/ip_fw_private.h
  head/sys/netpfil/ipfw/ip_fw_sockopt.c

Modified: head/sbin/ipfw/ipfw2.c
==============================================================================
--- head/sbin/ipfw/ipfw2.c	Tue Nov  3 09:50:10 2015	(r290329)
+++ head/sbin/ipfw/ipfw2.c	Tue Nov  3 10:21:53 2015	(r290330)
@@ -4983,10 +4983,48 @@ ipfw_flush(int force)
 static struct _s_x intcmds[] = {
       { "talist",	TOK_TALIST },
       { "iflist",	TOK_IFLIST },
+      { "olist",	TOK_OLIST },
       { "vlist",	TOK_VLIST },
       { NULL, 0 }
 };
 
+static void
+ipfw_list_objects(int ac, char *av[])
+{
+	ipfw_obj_lheader req, *olh;
+	ipfw_obj_ntlv *ntlv;
+	size_t sz;
+	int i;
+
+	memset(&req, 0, sizeof(req));
+	sz = sizeof(req);
+	if (do_get3(IP_FW_DUMP_SRVOBJECTS, &req.opheader, &sz) != 0)
+		if (errno != ENOMEM)
+			return;
+
+	sz = req.size;
+	if ((olh = calloc(1, sz)) == NULL)
+		return;
+
+	olh->size = sz;
+	if (do_get3(IP_FW_DUMP_SRVOBJECTS, &olh->opheader, &sz) != 0) {
+		free(olh);
+		return;
+	}
+
+	if (olh->count > 0)
+		printf("Objects list:\n");
+	else
+		printf("There are no objects\n");
+	ntlv = (ipfw_obj_ntlv *)(olh + 1);
+	for (i = 0; i < olh->count; i++) {
+		printf(" kidx: %4d\ttype: %2d\tname: %s\n", ntlv->idx,
+		    ntlv->head.type, ntlv->name);
+		ntlv++;
+	}
+	free(olh);
+}
+
 void
 ipfw_internal_handler(int ac, char *av[])
 {
@@ -5005,6 +5043,9 @@ ipfw_internal_handler(int ac, char *av[]
 	case TOK_TALIST:
 		ipfw_list_ta(ac, av);
 		break;
+	case TOK_OLIST:
+		ipfw_list_objects(ac, av);
+		break;
 	case TOK_VLIST:
 		ipfw_list_values(ac, av);
 		break;

Modified: head/sbin/ipfw/ipfw2.h
==============================================================================
--- head/sbin/ipfw/ipfw2.h	Tue Nov  3 09:50:10 2015	(r290329)
+++ head/sbin/ipfw/ipfw2.h	Tue Nov  3 10:21:53 2015	(r290330)
@@ -227,6 +227,7 @@ enum tokens {
 	TOK_LOCK,
 	TOK_UNLOCK,
 	TOK_VLIST,
+	TOK_OLIST,
 };
 
 /*

Modified: head/sys/netinet/ip_fw.h
==============================================================================
--- head/sys/netinet/ip_fw.h	Tue Nov  3 09:50:10 2015	(r290329)
+++ head/sys/netinet/ip_fw.h	Tue Nov  3 10:21:53 2015	(r290330)
@@ -107,6 +107,7 @@ typedef struct _ip_fw3_opheader {
 #define	IP_FW_NAT44_XGETLOG	115	/* Get log from NAT44 instance */
 
 #define	IP_FW_DUMP_SOPTCODES	116	/* Dump available sopts/versions */
+#define	IP_FW_DUMP_SRVOBJECTS	117	/* Dump existing named objects */
 
 /*
  * The kernel representation of ipfw rules is made of a list of

Modified: head/sys/netpfil/ipfw/ip_fw_private.h
==============================================================================
--- head/sys/netpfil/ipfw/ip_fw_private.h	Tue Nov  3 09:50:10 2015	(r290329)
+++ head/sys/netpfil/ipfw/ip_fw_private.h	Tue Nov  3 10:21:53 2015	(r290330)
@@ -673,6 +673,7 @@ int ipfw_objhash_free_idx(struct namedob
 int ipfw_objhash_alloc_idx(void *n, uint16_t *pidx);
 void ipfw_objhash_set_funcs(struct namedobj_instance *ni,
     objhash_hash_f *hash_f, objhash_cmp_f *cmp_f);
+void ipfw_export_obj_ntlv(struct named_object *no, ipfw_obj_ntlv *ntlv);
 void ipfw_init_obj_rewriter(void);
 void ipfw_destroy_obj_rewriter(void);
 void ipfw_add_obj_rewriter(struct opcode_obj_rewrite *rw, size_t count);

Modified: head/sys/netpfil/ipfw/ip_fw_sockopt.c
==============================================================================
--- head/sys/netpfil/ipfw/ip_fw_sockopt.c	Tue Nov  3 09:50:10 2015	(r290329)
+++ head/sys/netpfil/ipfw/ip_fw_sockopt.c	Tue Nov  3 10:21:53 2015	(r290330)
@@ -119,6 +119,8 @@ static int manage_sets(struct ip_fw_chai
     struct sockopt_data *sd);
 static int dump_soptcodes(struct ip_fw_chain *chain, ip_fw3_opheader *op3,
     struct sockopt_data *sd);
+static int dump_srvobjects(struct ip_fw_chain *chain, ip_fw3_opheader *op3,
+    struct sockopt_data *sd);
 
 /* ctl3 handler data */
 struct mtx ctl3_lock;
@@ -146,6 +148,7 @@ static struct ipfw_sopt_handler	scodes[]
 	{ 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 },
+	{ IP_FW_DUMP_SRVOBJECTS,0,	HDIR_GET,	dump_srvobjects },
 };
 
 static int
@@ -1876,6 +1879,16 @@ struct dump_args {
 	int		rcounters;	/* counters */
 };
 
+void
+ipfw_export_obj_ntlv(struct named_object *no, ipfw_obj_ntlv *ntlv)
+{
+
+	ntlv->head.type = no->etlv;
+	ntlv->head.length = sizeof(*ntlv);
+	ntlv->idx = no->kidx;
+	strlcpy(ntlv->name, no->name, sizeof(ntlv->name));
+}
+
 /*
  * Export named object info in instance @ni, identified by @kidx
  * to ipfw_obj_ntlv. TLV is allocated from @sd space.
@@ -1896,11 +1909,7 @@ export_objhash_ntlv(struct namedobj_inst
 	if (ntlv == NULL)
 		return (ENOMEM);
 
-	ntlv->head.type = no->etlv;
-	ntlv->head.length = sizeof(*ntlv);
-	ntlv->idx = no->kidx;
-	strlcpy(ntlv->name, no->name, sizeof(ntlv->name));
-
+	ipfw_export_obj_ntlv(no, ntlv);
 	return (0);
 }
 
@@ -2803,6 +2812,54 @@ ipfw_del_obj_rewriter(struct opcode_obj_
 	return (0);
 }
 
+static void
+export_objhash_ntlv_internal(struct namedobj_instance *ni,
+    struct named_object *no, void *arg)
+{
+	struct sockopt_data *sd;
+	ipfw_obj_ntlv *ntlv;
+
+	sd = (struct sockopt_data *)arg;
+	ntlv = (ipfw_obj_ntlv *)ipfw_get_sopt_space(sd, sizeof(*ntlv));
+	if (ntlv == NULL)
+		return;
+	ipfw_export_obj_ntlv(no, ntlv);
+}
+
+/*
+ * Lists all service objects.
+ * Data layout (v0)(current):
+ * Request: [ ipfw_obj_lheader ] size = ipfw_cfg_lheader.size
+ * Reply: [ ipfw_obj_lheader [ ipfw_obj_ntlv x N ] (optional) ]
+ * Returns 0 on success
+ */
+static int
+dump_srvobjects(struct ip_fw_chain *chain, ip_fw3_opheader *op3,
+    struct sockopt_data *sd)
+{
+	ipfw_obj_lheader *hdr;
+	int count;
+
+	hdr = (ipfw_obj_lheader *)ipfw_get_sopt_header(sd, sizeof(*hdr));
+	if (hdr == NULL)
+		return (EINVAL);
+
+	IPFW_UH_RLOCK(chain);
+	count = ipfw_objhash_count(CHAIN_TO_SRV(chain));
+	hdr->size = sizeof(ipfw_obj_lheader) + count * sizeof(ipfw_obj_ntlv);
+	if (sd->valsize < hdr->size) {
+		IPFW_UH_RUNLOCK(chain);
+		return (ENOMEM);
+	}
+	hdr->count = count;
+	hdr->objsize = sizeof(ipfw_obj_ntlv);
+	if (count > 0)
+		ipfw_objhash_foreach(CHAIN_TO_SRV(chain),
+		    export_objhash_ntlv_internal, sd);
+	IPFW_UH_RUNLOCK(chain);
+	return (0);
+}
+
 /*
  * Compares two sopt handlers (code, version and handler ptr).
  * Used both as qsort() and bsearch().


More information about the svn-src-all mailing list