1
0
mirror of https://github.com/fwbuilder/fwbuilder synced 2025-10-15 23:18:51 +02:00

* OSConfigurator_bsd.cpp (OSConfigurator_bsd::configureInterfaces):

New feature: generated script adds and removes CARP interfaces
incrementally. This means it is not going to run ifconfig command
to create carp interface if it is already there and will run
"ifconfig carp1 destroy" command if interface carp1 has been
removed in fwbuilder GUI to delete it on the firewall.
This commit is contained in:
Vadim Kurland 2010-02-14 06:16:44 +00:00
parent 81ee822cd3
commit d6d0dd0e41
7 changed files with 198 additions and 113 deletions

View File

@ -1 +1 @@
#define BUILD_NUM 2523
#define BUILD_NUM 2524

View File

@ -1,5 +1,12 @@
2010-02-13 vadim <vadim@vk.crocodile.org>
* OSConfigurator_bsd.cpp (OSConfigurator_bsd::configureInterfaces):
New feature: generated script adds and removes CARP interfaces
incrementally. This means it is not going to run ifconfig command
to create carp interface if it is already there and will run
"ifconfig carp1 destroy" command if interface carp1 has been
removed in fwbuilder GUI to delete it on the firewall.
* OSConfigurator_bsd.cpp (OSConfigurator_bsd::configureInterfaces):
New feature: incremental VLAN interface management for OpenBSD and
FreeBSD. When user adds or removes VLAN subinterface in fwbuilder

View File

@ -36,6 +36,9 @@
#include "fwbuilder/FailoverClusterGroup.h"
#include "fwbuilder/StateSyncClusterGroup.h"
#include "interfaceProperties.h"
#include "interfacePropertiesObjectFactory.h"
#include <QTextStream>
#include <QString>
@ -190,9 +193,23 @@ string OSConfigurator_bsd::printFunctions()
ostr << update_vlans.expand().toStdString();
}
if ( options->getBool("configure_carp_interfaces") )
{
Configlet update_carp(fw, "bsd", "update_carp");
update_carp.removeComments();
ostr << update_carp.expand().toStdString();
}
return ostr.str();
}
bool compare_names(FWObject *a, FWObject *b)
{
if (a->getName() < b->getName()) return true;
return false;
}
string OSConfigurator_bsd::configureInterfaces()
{
ostringstream ostr;
@ -235,61 +252,6 @@ string OSConfigurator_bsd::configureInterfaces()
}
}
if ( options->getBool("configure_interfaces") )
{
ostr << endl;
list<FWObject*> all_interfaces = fw->getByTypeDeep(Interface::TYPENAME);
for (list<FWObject*>::iterator i=all_interfaces.begin();
i != all_interfaces.end(); ++i )
{
Interface *iface = Interface::cast(*i);
assert(iface);
if (!iface->isRegular()) continue;
if (iface->isFailoverInterface()) continue;
list<FWObject*> all_addr = iface->getByType(IPv4::TYPENAME);
list<FWObject*> all_ipv6 = iface->getByType(IPv6::TYPENAME);
all_addr.insert(all_addr.begin(), all_ipv6.begin(), all_ipv6.end());
const InetAddr *netmask = iface->getNetmaskPtr();
list<pair<InetAddr,InetAddr> > all_addresses;
for (list<FWObject*>::iterator j = all_addr.begin();
j != all_addr.end(); ++j)
{
Address *iaddr = Address::cast(*j);
const InetAddr *ipaddr = iaddr->getAddressPtr();
const InetAddr *ipnetm = iaddr->getNetmaskPtr();
all_addresses.push_back(
pair<InetAddr,InetAddr>(*ipaddr, *ipnetm));
}
set<const Address*>::iterator it;
for (it=virtual_addresses.begin(); it!=virtual_addresses.end(); ++it)
{
const Address *addr = *it;
FWObject *iaddr = findAddressFor(addr, fw );
if (iaddr!=NULL)
{
Interface *iface_2 = Interface::cast(iaddr->getParent());
if (iface_2 == iface)
{
all_addresses.push_back(
pair<InetAddr,InetAddr>(
*(addr->getAddressPtr()), *netmask));
}
}
}
ostr << updateAddressesOfInterfaceCall(iface, all_addresses) << endl;
}
ostr << endl;
}
if ( options->getBool("configure_carp_interfaces") )
{
/*
@ -298,19 +260,9 @@ string OSConfigurator_bsd::configureInterfaces()
* the firewall here, we get both its normal interfaces and a copy of
* cluster interfaces.
*
* Need to generate commands
*
* ifconfig carpN create
*
* ifconfig carpN vhid vhid [pass password] [carpdev carpdev] \
* [advbase advbase] [advskew advskew] [state state] ipaddress \
* netmask mask
*
* for pfsync and CARP see http://www.kernel-panic.it/openbsd/carp/
* "Redundant firewalls with OpenBSD, CARP and pfsync"
*/
ostringstream carp_output;
bool have_carp_interfaces = false;
QStringList carp_interfaces;
FWObjectTypedChildIterator i=fw->findByType(Interface::TYPENAME);
for ( ; i!=i.end(); ++i )
@ -331,6 +283,8 @@ string OSConfigurator_bsd::configureInterfaces()
iface->getFirstByType(FailoverClusterGroup::TYPENAME);
if (failover_group && failover_group->getStr("type") == "carp")
{
carp_interfaces.push_back(iface->getName().c_str());
FWOptions *failover_opts =
FailoverClusterGroup::cast(failover_group)->getOptionsObject();
string carp_password = failover_opts->getStr("carp_password");
@ -342,70 +296,109 @@ string OSConfigurator_bsd::configureInterfaces()
if (master_advskew < 0) master_advskew = 0;
if (default_advskew < 0) default_advskew = 0;
if (master_advskew == default_advskew) default_advskew++;
have_carp_interfaces = true;
carp_output << "ifconfig " << iface->getName() << " create" << endl;
carp_output << "ifconfig " << iface->getName()
<< " vhid " << vhid
<< " pass " << carp_password
<< " ";
if (!base_interface.empty())
carp_output << " carpdev " << base_interface;
// the default for advbase is 1, skip it if use_advskew < 1
// (can be -1 if not defined at all)
if (advbase > 1)
carp_output << " advbase " << advbase;
int use_advskew;
if (master)
use_advskew = master_advskew;
else
use_advskew = default_advskew;
// the default for advskew is 0, skip it if use_advskew == 0
if (use_advskew > 0)
carp_output << " advskew " << use_advskew;
Configlet configlet(fw, "bsd", "carp_interface");
configlet.removeComments();
configlet.collapseEmptyStrings(true);
configlet.setVariable("carp_interface", iface->getName().c_str());
configlet.setVariable("have_advbase", advbase > 1);
configlet.setVariable("advbase", advbase);
configlet.setVariable("have_advskew", use_advskew > 0);
configlet.setVariable("advskew", use_advskew);
configlet.setVariable("have_base_inetrface", !base_interface.empty());
configlet.setVariable("base_inetrface", base_interface.c_str());
configlet.setVariable("carp_password", carp_password.c_str());
configlet.setVariable("vhid", vhid.c_str());
carp_output << endl;
carp_output << configlet.expand().toStdString() << endl;
}
}
if (carp_interfaces.size() > 0)
{
ostr << "sync_carp_interfaces "
<< carp_interfaces.join(" ").toStdString()
<< endl;
ostr << carp_output.str() << endl;
}
}
if ( options->getBool("configure_interfaces") )
{
ostr << endl;
std::auto_ptr<interfaceProperties> int_prop(
interfacePropertiesObjectFactory::getInterfacePropertiesObject(
fw->getStr("host_OS")));
list<FWObject*> all_interfaces = fw->getByTypeDeep(Interface::TYPENAME);
all_interfaces.sort(compare_names);
for (list<FWObject*>::iterator i=all_interfaces.begin();
i != all_interfaces.end(); ++i )
{
Interface *iface = Interface::cast(*i);
assert(iface);
if (!iface->isRegular()) continue;
//if (iface->isFailoverInterface()) continue;
QStringList update_addresses;
QStringList ignore_addresses;
if (int_prop->manageIpAddresses(iface, update_addresses, ignore_addresses))
{
// unfortunately addresses in update_addresses are in
// the form of address/masklen but OpenBSD ifconfig
// uses hex netmask representation and so should we.
// Will ignore update_addresses and ignore_addresses and
// build our own list here. Returned value of manageIpAddresses()
// is useful though.
list<FWObject*> all_addr = iface->getByType(IPv4::TYPENAME);
list<FWObject*> all_ipv6 = iface->getByType(IPv6::TYPENAME);
all_addr.insert(all_addr.begin(), all_ipv6.begin(), all_ipv6.end());
const InetAddr *netmask = iface->getNetmaskPtr();
list<pair<InetAddr,InetAddr> > all_addresses;
for (list<FWObject*>::iterator j = all_addr.begin();
j != all_addr.end(); ++j)
j != all_addr.end(); ++j)
{
Address *address = Address::cast(*j);
const InetAddr *addr = address->getAddressPtr();
const InetAddr *mask = address->getNetmaskPtr();
carp_output << "ifconfig " << iface->getName();
if (addr->isV6())
carp_output << " inet6";
else
carp_output << " inet";
carp_output << " " << addr->toString();
carp_output << " prefixlen " << mask->getLength();
carp_output << endl;
Address *iaddr = Address::cast(*j);
const InetAddr *ipaddr = iaddr->getAddressPtr();
const InetAddr *ipnetm = iaddr->getNetmaskPtr();
all_addresses.push_back(
pair<InetAddr,InetAddr>(*ipaddr, *ipnetm));
}
set<const Address*>::iterator it;
for (it=virtual_addresses.begin(); it!=virtual_addresses.end(); ++it)
{
const Address *addr = *it;
FWObject *iaddr = findAddressFor(addr, fw );
if (iaddr!=NULL)
{
Interface *iface_2 = Interface::cast(iaddr->getParent());
if (iface_2 == iface)
{
all_addresses.push_back(
pair<InetAddr,InetAddr>(
*(addr->getAddressPtr()), *netmask));
}
}
}
ostr << updateAddressesOfInterfaceCall(iface, all_addresses) << endl;
}
}
if (have_carp_interfaces)
{
ostr << "$SYSCTL -w net.inet.carp.allow=1" << endl;
ostr << carp_output.str() << endl;
}
ostr << endl;
}

View File

@ -0,0 +1,17 @@
## -*- mode: shell-script; -*-
##
## Lines that start with "##" will be removed before this code is
## added to the generated script. Regular shell comments can be added
## using single "#", these will appear in the script.
##
##
## CARP
## ifconfig carp-interface [advbase n] [advskew n] [carpdev iface]
## [pass passphrase] [state state] [vhid host-id]
##
## for pfsync and CARP see http://www.kernel-panic.it/openbsd/carp/
## "Redundant firewalls with OpenBSD, CARP and pfsync"
$IFCONFIG {{$carp_interface}} vhid {{$vhid}} pass {{$carp_password}} {{if have_advbase}} advbase {{$advbase}}{{endif}} {{if have_advskew}} advskew {{$advskew}}{{endif}} {{if have_base_inetrface}} carpdev {{$base_inetrface}}{{endif}}

View File

@ -0,0 +1,48 @@
## -*- mode: shell-script; -*-
##
## To be able to make changes to the part of configuration created
## from this configlet you need to copy this file to the directory
## fwbuilder/configlets/bsd/ in your home directory and modify it.
## Double "##" comments are removed during processing but single "#"
## comments are be retained and appear in the generated script. Empty
## lines are removed as well.
##
## Configlets support simple macro language with these constructs:
## {{$var}} is variable expansion
## {{if var}} is conditional operator.
##
############ CARP interfaces ############################################
##
## This function synchronizes carp interfaces between fwbuilder objects
## and actual configuration of the firewall machine. Carp interfaces not
## listed as arguments will be deleted and those in the arguments will be
## created if missing.
##
## This function only executes "ifconfig carp0 create" or "ifconfig carp0 destroy"
## commands. Other parameters of carp interfaces should be set up separately
## (see configlet carp_interface for that)
##
## sync_carp_interfaces carp0 carp1
sync_carp_interfaces() {
$IFCONFIG -A | awk -v IGNORED="$*" \
'BEGIN {
split(IGNORED,ignored_arr);
for (a in ignored_arr) {ii=ignored_arr[a]":"; ignored_dict[ii]=1;}
}
($1 ~ /^carp[0-9]/ && !($1 in ignored_dict)) {print $1;}' | sed 's/://' |\
while read intf; do
echo "# Deleting carp interface $intf"
$FWBDEBUG $IFCONFIG $intf destroy
done
for intf in $*; do
$IFCONFIG $intf >/dev/null 2>&1 || {
echo "# Creating carp interface $intf"
$SYSCTL -w net.inet.carp.allow=1
$FWBDEBUG $IFCONFIG $intf create
}
done
}

View File

@ -1200,10 +1200,11 @@
<Option name="vlan_id">100</Option>
</InterfaceOptions>
</Interface>
<IPv4 id="id16633X39764" name="pf_cluster_1:carp0:ip-1" comment="" ro="False" address="172.24.0.1" netmask="255.255.255.0"/>
</Library>
<Library id="id1495X69605" color="#d2ffd0" name="User" comment="" ro="False">
<ObjectGroup id="id1502X69605" name="Clusters" comment="" ro="False">
<Cluster id="id3631X95766" host_OS="openbsd" inactive="False" lastCompiled="1248551815" lastInstalled="0" lastModified="1264267318" platform="pf" name="pf_cluster_1" comment=" " ro="False">
<Cluster id="id3631X95766" host_OS="openbsd" inactive="False" lastCompiled="1248551815" lastInstalled="0" lastModified="1266123526" platform="pf" name="pf_cluster_1" comment=" " ro="False">
<NAT id="id3640X95766" name="NAT" comment="" ro="False" ipv4_rule_set="False" ipv6_rule_set="False" top_rule_set="True">
<NATRule id="id3162X39764" disabled="False" position="0" action="Translate" comment="">
<OSrc neg="False">
@ -1461,7 +1462,6 @@
</Routing>
<Interface id="id3642X95766" dedicated_failover="False" dyn="False" label="pf_clsuter_1 carp0" mgmt="False" security_level="0" unnum="False" unprotected="False" name="carp0" comment="" ro="False">
<IPv4 id="id3647X95766" name="pf_cluster_1:carp0:ip" comment="" ro="False" address="172.24.0.1" netmask="255.255.255.0"/>
<IPv4 id="id16633X39764" name="pf_cluster_1:carp0:ip-1" comment="" ro="False" address="172.24.0.1" netmask="255.255.255.0"/>
<InterfaceOptions>
<Option name="iface_mtu">1500</Option>
<Option name="type">carp</Option>

20
test/pf/run-clusters.all Executable file
View File

@ -0,0 +1,20 @@
#!/bin/sh
#XMLFILE="objects-for-regression-tests.fwb"
#fwbedit list -f $XMLFILE -o /User/Firewalls -c -F%name% | \
# sort | while read fwobj
#do
# echo "echo"
# echo "echo \"============================ $fwobj\""
# echo "fwb_pf -v -f $XMLFILE -xt $fwobj"
#done
XMLFILE="cluster-tests.fwb"
fwbedit list -f $XMLFILE -o /User/Clusters -c -F%name% | \
sort | while read fwobj
do
echo "echo"
echo "echo \"============================ $fwobj\""
echo "fwb_pf -v -f $XMLFILE -xt -xc $fwobj"
done