Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 7 Aug 2014 22:08:43 +0000 (UTC)
From:      Alexander V. Chernikov <melifaro@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r269694 - projects/ipfw/sys/netpfil/ipfw
Message-ID:  <53e3f8ec.2cac.2ef9c6e1@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: melifaro
Date: Thu Aug  7 22:08:43 2014
New Revision: 269694
URL: http://svnweb.freebsd.org/changeset/base/269694

Log:
  Since all of base IP_FW opcodes has been converted to IP_FW3,
  switch default sopt handler to ipfw_clt3.
  Add some comments for ipfw_get_sopt* api.

Modified:
  projects/ipfw/sys/netpfil/ipfw/ip_fw2.c
  projects/ipfw/sys/netpfil/ipfw/ip_fw_private.h
  projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c

Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw2.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw2.c	Thu Aug  7 21:56:46 2014	(r269693)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw2.c	Thu Aug  7 22:08:43 2014	(r269694)
@@ -2735,7 +2735,7 @@ vnet_ipfw_init(const void *unused)
 	 * In layer2 we have the same behaviour, except that V_ether_ipfw
 	 * is checked on each packet because there are no pfil hooks.
 	 */
-	V_ip_fw_ctl_ptr = ipfw_ctl;
+	V_ip_fw_ctl_ptr = ipfw_ctl3;
 	error = ipfw_attach_hooks(1);
 	return (error);
 }

Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_private.h
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_private.h	Thu Aug  7 21:56:46 2014	(r269693)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_private.h	Thu Aug  7 22:08:43 2014	(r269694)
@@ -500,7 +500,6 @@ int ipfw_list_ifaces(struct ip_fw_chain 
 void ipfw_init_skipto_cache(struct ip_fw_chain *chain);
 void ipfw_destroy_skipto_cache(struct ip_fw_chain *chain);
 int ipfw_find_rule(struct ip_fw_chain *chain, uint32_t key, uint32_t id);
-int ipfw_ctl(struct sockopt *sopt);
 int ipfw_ctl3(struct sockopt *sopt);
 int ipfw_chk(struct ip_fw_args *args);
 void ipfw_reap_rules(struct ip_fw *head);

Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c	Thu Aug  7 21:56:46 2014	(r269693)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c	Thu Aug  7 22:08:43 2014	(r269694)
@@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$");
 #include <security/mac/mac_framework.h>
 #endif
 
+static int ipfw_ctl(struct sockopt *sopt);
 static int check_ipfw_rule_body(ipfw_insn *cmd, int cmd_len,
     struct rule_check_info *ci);
 static int check_ipfw_rule1(struct ip_fw_rule *rule, int size,
@@ -2102,6 +2103,93 @@ add_rules(struct ip_fw_chain *chain, ip_
 	return (error);
 }
 
+/*
+ * Writes data accumulated in @sd to sockopt buffer.
+ * Zeroes internal @sd buffer.
+ */
+static int
+ipfw_flush_sopt_data(struct sockopt_data *sd)
+{
+	int error;
+	size_t sz;
+
+	if ((sz = sd->koff) == 0)
+		return (0);
+
+	if (sd->sopt->sopt_dir == SOPT_GET) {
+		error = sooptcopyout(sd->sopt, sd->kbuf, sz);
+		if (error != 0)
+			return (error);
+	}
+
+	memset(sd->kbuf, 0, sd->ksize);
+	sd->ktotal += sd->koff;
+	sd->koff = 0;
+	if (sd->ktotal + sd->ksize < sd->valsize)
+		sd->kavail = sd->ksize;
+	else
+		sd->kavail = sd->valsize - sd->ktotal;
+
+	/* Update sopt buffer */
+	sd->sopt->sopt_valsize = sd->kavail;
+	sd->sopt->sopt_val = sd->sopt_val + sd->ktotal;
+
+	return (0);
+}
+
+/*
+ * Ensures that @sd buffer has contigious @neeeded number of
+ * bytes.
+ *
+ * Returns pointer to requested space or NULL.
+ */
+caddr_t
+ipfw_get_sopt_space(struct sockopt_data *sd, size_t needed)
+{
+	int error;
+	caddr_t addr;
+
+	if (sd->kavail < needed) {
+		/*
+		 * Flush data and try another time.
+		 */
+		error = ipfw_flush_sopt_data(sd);
+
+		if (sd->kavail < needed || error != 0)
+			return (NULL);
+	}
+
+	addr = sd->kbuf + sd->koff;
+	sd->koff += needed;
+	sd->kavail -= needed;
+	return (addr);
+}
+
+/*
+ * Requests @needed contigious bytes from @sd buffer.
+ * Function is used to notify subsystem that we are
+ * interesed in first @needed bytes (request header)
+ * and the rest buffer can be safely zeroed.
+ *
+ * Returns pointer to requested space or NULL.
+ */
+caddr_t
+ipfw_get_sopt_header(struct sockopt_data *sd, size_t needed)
+{
+	caddr_t addr;
+
+	if ((addr = ipfw_get_sopt_space(sd, needed)) == NULL)
+		return (NULL);
+
+	if (sd->kavail > 0)
+		memset(sd->kbuf + sd->koff, 0, sd->kavail);
+	
+	return (addr);
+}
+
+/*
+ * New sockopt handler.
+ */
 int
 ipfw_ctl3(struct sockopt *sopt)
 {
@@ -2113,15 +2201,12 @@ ipfw_ctl3(struct sockopt *sopt)
 	struct sockopt_data sdata;
 	ip_fw3_opheader *op3 = NULL;
 
-	/* Do not check privs twice untile we're called from ipfw_ctl() */
-#if 0
 	error = priv_check(sopt->sopt_td, PRIV_NETINET_IPFW);
 	if (error != 0)
 		return (error);
-#endif
 
 	if (sopt->sopt_name != IP_FW3)
-		return (ENOTSUP);
+		return (ipfw_ctl(sopt));
 
 	chain = &V_layer3_chain;
 	error = 0;
@@ -2328,10 +2413,6 @@ ipfw_ctl(struct sockopt *sopt)
 	uint32_t opt;
 	struct rule_check_info ci;
 
-	error = priv_check(sopt->sopt_td, PRIV_NETINET_IPFW);
-	if (error)
-		return (error);
-
 	chain = &V_layer3_chain;
 	error = 0;
 
@@ -2339,10 +2420,6 @@ ipfw_ctl(struct sockopt *sopt)
 	valsize = sopt->sopt_valsize;
 	opt = sopt->sopt_name;
 
-	/* Pass IP_FW3 to a new handler */
-	if (opt == IP_FW3)
-		return (ipfw_ctl3(sopt));
-
 	/*
 	 * Disallow modifications in really-really secure mode, but still allow
 	 * the logging counters to be reset.
@@ -2634,73 +2711,6 @@ ipfw_ctl(struct sockopt *sopt)
 	return (error);
 #undef RULE_MAXSIZE
 }
-
-static int
-ipfw_flush_sopt_data(struct sockopt_data *sd)
-{
-	int error;
-	size_t sz;
-
-	if ((sz = sd->koff) == 0)
-		return (0);
-
-	if (sd->sopt->sopt_dir == SOPT_GET) {
-		error = sooptcopyout(sd->sopt, sd->kbuf, sz);
-		if (error != 0)
-			return (error);
-	}
-
-	memset(sd->kbuf, 0, sd->ksize);
-	sd->ktotal += sd->koff;
-	sd->koff = 0;
-	if (sd->ktotal + sd->ksize < sd->valsize)
-		sd->kavail = sd->ksize;
-	else
-		sd->kavail = sd->valsize - sd->ktotal;
-
-	/* Update sopt buffer */
-	sd->sopt->sopt_valsize = sd->kavail;
-	sd->sopt->sopt_val = sd->sopt_val + sd->ktotal;
-
-	return (0);
-}
-
-caddr_t
-ipfw_get_sopt_space(struct sockopt_data *sd, size_t needed)
-{
-	int error;
-	caddr_t addr;
-
-	if (sd->kavail < needed) {
-		/*
-		 * Flush data and try another time.
-		 */
-		error = ipfw_flush_sopt_data(sd);
-
-		if (sd->kavail < needed || error != 0)
-			return (NULL);
-	}
-
-	addr = sd->kbuf + sd->koff;
-	sd->koff += needed;
-	sd->kavail -= needed;
-	return (addr);
-}
-
-caddr_t
-ipfw_get_sopt_header(struct sockopt_data *sd, size_t needed)
-{
-	caddr_t addr;
-
-	if ((addr = ipfw_get_sopt_space(sd, needed)) == NULL)
-		return (NULL);
-
-	if (sd->kavail > 0)
-		memset(sd->kbuf + sd->koff, 0, sd->kavail);
-	
-	return (addr);
-}
-
 #define	RULE_MAXSIZE	(256*sizeof(u_int32_t))
 
 /* Functions to convert rules 7.2 <==> 8.0 */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?53e3f8ec.2cac.2ef9c6e1>