Project

General

Profile

Feature #12945

Updated by Reid Linnemann over 2 years ago

As indicated by Viktor Gurov: 
 > pfSense_ipfw_*() functions have been rewritten to use shell scripts, which is slow, and can be a serious issue for the large (>1k clients) captive   
 > > portal installations. These shell scripts should be rewritten as C functions (maybe not all): 
 > pfSense_pf_flush_anchor(): https://gitlab.netgate.com/pfSense/pfSense/-/blob/viktor-captive/src/etc/inc/captiveportal.inc#L1064 
 > pfSense_pf_get_cp_anchor_pipes(): https://gitlab.netgate.com/pfSense/pfSense/-/blob/viktor-captive/src/etc/inc/captiveportal.inc#L1116 
 > pfSense_pf_mod_table(): https://gitlab.netgate.com/pfSense/pfSense/-/blob/viktor-captive/src/etc/inc/captiveportal.inc#L1129 
 > pfSense_pf_get_table_counters(): https://gitlab.netgate.com/pfSense/pfSense/-/blob/viktor-captive/src/etc/inc/captiveportal.inc#L1764 
 > pfSense_pf_anchor_rules(): https://gitlab.netgate.com/pfSense/pfSense/-/blob/viktor-captive/src/etc/inc/captiveportal.inc#L3054 
 >  
 > Some of these may have been introduced into libpfctl already. 
 Some of this code has changed in the interim. 
 For reference, here is what looks to be needed: 
 <pre><code class="php"> 
 /* XXX OPTIMIZE: pfSense_pf_flush_anchor($anchor, $type = 'rules/nat/ether') */ 
 mwexec("/sbin/pfctl -a {$cpzoneprefix}_passthrumac/{$host} -F ethernet"); 

 /* XXX OPTIMIZE: pfSense_pf_flush_anchor($anchor, $type = 'rules/nat/ether') */ 
 mwexec("/sbin/pfctl -a {$cpzoneprefix}_{$anchor}/{$host} -F ether"); 

 /* XXX OPTIMIZE: list($pipeup, $pipedown) = pfSense_pf_get_cp_anchor_pipes($anchor); */ 
 $pipeup = mwexec("/sbin/pfctl -a {$cpzoneprefix}_{$anchor}/{$host} -se | cut -d' ' -f 17 | head -n1"); 

 /* XXX OPTIMIZE: list($pipeup, $pipedown) = pfSense_pf_get_cp_anchor_pipes($anchor) */ 
 exec("/sbin/pfctl -a {$cpzoneprefix}_{$anchor}mac/{$host} -se | awk -F'[()]' '{print $2; exit}'", $result, $retval); 

 /* XXX OPTIMIZE: array('output_pkts', 'output_bytes', 'input_pkts', 'input_bytes') = pfSense_pf_get_table_counters($table) */ 
 exec("/sbin/pfctl -a {$anchor}/{$ip} -se -v 2>/dev/null | grep Bytes", $result); 

 /* Load rules for a host directly into pf = pfSense_pf_anchor_rules($anchor, $host, $rules) */ 
 function captiveportal_load_pfctl($anchor, $host, $rules) { 
	 global $g, $cpzone; 

	 if (!empty($rules)) { 
		 mwexec("/usr/bin/printf \"{$rules}\" | /sbin/pfctl -a {$anchor}/{$host} -f-"); 
	 } else { 
		 log_error("CP zone ${cpzone}: {$anchor} rules are empty for {$host}"); 
	 } 
 } 

 /* Zero anchor counters = pfSense_pf_zero_anchor_counters($anchor) */ 
 function captiveportal_anchor_zerocnt($ip, $anchor = 'auth') { 
	 global $config, $cpzone; 
	 $cpzoneprefix = CPPREFIX . $config['captiveportal'][$cpzone]['zoneid']; 

	 mwexec("/sbin/pfctl -z -a {$cpzoneprefix}_{$anchor}/{$ip}"); 
 } 

 </code></pre> 

Back