<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Package development - firewall rules]]></title><description><![CDATA[<p dir="auto">I'm developing a pfSense package and I would like to generate one or more firewall rules from my package. I used the existing packages as an example and found the XML element '&lt;filter_rules_needed&gt;'. It looks like this is what is need (correct me when I'm wrong!). But this method is never being called (I think) by PFSense.</p>
<p dir="auto"><strong>My package config XML:</strong></p>
<pre><code>
 &lt;packagegui&gt;&lt;description&gt;My package&lt;/description&gt;

    &lt;name&gt;MyPackage&lt;/name&gt;
    &lt;version&gt;0.1&lt;/version&gt;
    &lt;title&gt;My Package&lt;/title&gt;
    &lt;include_file&gt;/usr/local/pkg/mypackage.inc&lt;/include_file&gt;
    ...
    &lt;filter_rules_needed&gt;mypackage_generate_rules&lt;/filter_rules_needed&gt;&lt;/packagegui&gt; 
</code></pre>
<p dir="auto"><strong>My package include file:</strong></p>
<pre><code>
require_once('util.inc');
require_once('filter.inc');
require_once('interfaces.inc');
require_once('pfsense-utils.inc');
require_once('service-utils.inc');

function mypackage_generate_rules($sType)
{
	global $config;

	log_error("mypackage_generate_rules: ".$sType);

	$aInterfaces = explode(',', $config['installedpackages']['mypackage']['config'][0]['serverinterfaces']);
	$aInterfaces = array_map('convert_friendly_interface_to_real_interface_name', $aInterfaces);
	log_error("interfaces: ".print_r($aInterfaces, true));

	$sRules = "";
	switch($sType) 
	{
		case 'nat':
			// Nothing here yet.
			break;
		case 'filter':
		case 'rule':
			foreach ($aInterfaces as $sInterface)
			{
				$sRules .= "pass quick on {$sInterface} proto upd to port 1234 flags S/SA keep state label \"MyPackage: Test\"\n";
			}
			break;
		default:
			break;
	}

	return $sRules;
}

</code></pre>
<p dir="auto">PFSense doesn't create the rule as far as I can see. Also nothing in the logs; I would expect something like: 'mypackage_generate_rules' as I call log_error in this method.</p>
<p dir="auto">Anyone suggestions? Thanks!&lt;/filter_rules_needed&gt;</p>
]]></description><link>https://forum.netgate.com/topic/52652/package-development-firewall-rules</link><generator>RSS for Node</generator><lastBuildDate>Tue, 09 Jun 2026 20:50:22 GMT</lastBuildDate><atom:link href="https://forum.netgate.com/topic/52652.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 03 Feb 2013 20:41:05 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Package development - firewall rules on Sun, 10 Feb 2013 15:23:08 GMT]]></title><description><![CDATA[<p dir="auto">I finally figured out what went wrong. There where 2 issues.</p>
<ol>
<li>
<p dir="auto">The XML tag isn't used by PFSense at all, below a copy of the method PFSense uses to generate the rules (https://github.com/bsdperimeter/pfsense/blob/master/etc/inc/filter.inc).</p>
</li>
<li>
<p dir="auto">You should <strong>not</strong> use a subdirectory for your package; leave it in '/usr/local/pkg'. Otherwise the system won't find your 'generate_rules' function.</p>
</li>
</ol>
<pre><code>function discover_pkg_rules($ruletype) {
global $config, $g, $aliases;

/* Bail if there is no pkg directory, or if the package files might be out of sync. */
if(!is_dir("/usr/local/pkg") || file_exists('/conf/needs_package_sync'))
return "";

$rules = "";
$files = glob("/usr/local/pkg/*.inc");
foreach($files as $pkg_inc) {
update_filter_reload_status(sprintf(gettext('Checking for %1$s PF hooks in package %2$s'), $ruletype, $pkg_inc));
$pkg = basename($pkg_inc, ".inc");
$pkg_generate_rules = "{$pkg}_generate_rules";
if (!function_exists($pkg_generate_rules))
require_once($pkg_inc);
if(function_exists($pkg_generate_rules)) {
update_filter_reload_status(sprintf(gettext('Processing early %1$s rules for package %2$s'), $ruletype, $pkg_inc));
$tmprules = $pkg_generate_rules("$ruletype");
file_put_contents("{$g['tmp_path']}/rules.test.packages", $aliases . $tmprules);
$status = mwexec("/sbin/pfctl -nf {$g['tmp_path']}/rules.test.packages");
if ($status &lt;&gt; 0) {
$errorrules = sprintf(gettext("There was an error while parsing the package filter rules for %s."), $pkg_inc) . "\n";
log_error($errorrules);
file_put_contents("{$g['tmp_path']}/rules.packages.{$pkg}", "#{$errorrules}\n{$tmprules}\n");
continue;
}
$rules .= $tmprules;
}
}
return $rules;
}
</code></pre>
<p dir="auto">I hope that this info will help someone figuring it out a lot faster than I did  ;)</p>
]]></description><link>https://forum.netgate.com/post/378125</link><guid isPermaLink="true">https://forum.netgate.com/post/378125</guid><dc:creator><![CDATA[Sander88]]></dc:creator><pubDate>Sun, 10 Feb 2013 15:23:08 GMT</pubDate></item></channel></rss>