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>