mirror of
https://github.com/fwbuilder/fwbuilder
synced 2026-03-25 04:37:22 +01:00
* OSConfigurator_bsd.cpp (OSConfigurator_bsd::updateAddressesOfInterfaceCall):
New feature: incremental IP address management for OpenBSD and FreeBSD. Generated script adds and removes ipv4 and ipv6 addresses of interfaces as needed. When user adds an address in the fwbuilder object, the script adds it. Second run of the same script does nothing. If user removes an address in fwbuilder, generated script removes it from the interfaces to bring actual configuration of the machine in sync with fwbuilder objects.
This commit is contained in:
parent
fcceaf05f5
commit
01a79aeed5
@ -1,3 +1,14 @@
|
||||
2010-02-12 vadim <vadim@vk.crocodile.org>
|
||||
|
||||
* OSConfigurator_bsd.cpp (OSConfigurator_bsd::updateAddressesOfInterfaceCall):
|
||||
New feature: incremental IP address management for OpenBSD and
|
||||
FreeBSD. Generated script adds and removes ipv4 and ipv6 addresses
|
||||
of interfaces as needed. When user adds an address in the
|
||||
fwbuilder object, the script adds it. Second run of the same script
|
||||
does nothing. If user removes an address in fwbuilder, generated
|
||||
script removes it from the interfaces to bring actual configuration
|
||||
of the machine in sync with fwbuilder objects.
|
||||
|
||||
2010-02-10 yalovoy <yalovoy@gmail.com>
|
||||
* src/gui/RuleSetModel.cpp: fixes #1223: GUI crash while adding a host to a group
|
||||
To reproduce:
|
||||
|
||||
@ -59,45 +59,73 @@ string OSConfigurator_bsd::printKernelVarsCommands()
|
||||
return "";
|
||||
}
|
||||
|
||||
string OSConfigurator_bsd::updateAddressesOfInterfaceCall(
|
||||
Interface *iface, list<pair<InetAddr,InetAddr> > all_addresses)
|
||||
{
|
||||
QStringList arg1;
|
||||
arg1.push_back(iface->getName().c_str());
|
||||
|
||||
for (list<pair<InetAddr,InetAddr> >::iterator j = all_addresses.begin();
|
||||
j != all_addresses.end(); ++j)
|
||||
{
|
||||
InetAddr ipaddr = j->first;
|
||||
InetAddr ipnetm = j->second;
|
||||
|
||||
if (ipaddr.isV6())
|
||||
arg1.push_back(QString("%1/%2").arg(ipaddr.toString().c_str())
|
||||
.arg(ipnetm.getLength()));
|
||||
else
|
||||
{
|
||||
/*
|
||||
on OpenBSD ifconfig prints netmask of ipv4 addresses in hex
|
||||
|
||||
# ifconfig em0
|
||||
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
|
||||
lladdr 00:0c:29:83:4d:2f
|
||||
media: Ethernet autoselect (1000baseT full-duplex,master)
|
||||
status: active
|
||||
inet 10.1.1.50 netmask 0xffffff00 broadcast 10.1.1.255
|
||||
inet6 fe80::20c:29ff:fe83:4d2f%em0 prefixlen 64 scopeid 0x2
|
||||
*/
|
||||
int nbits = ipnetm.getLength();
|
||||
uint32_t netm = 0;
|
||||
while (nbits)
|
||||
{
|
||||
netm = netm >> 1;
|
||||
netm |= 1<<31;
|
||||
nbits--;
|
||||
}
|
||||
|
||||
arg1.push_back(QString("%1/0x%2")
|
||||
.arg(ipaddr.toString().c_str())
|
||||
.arg(netm, -8, 16));
|
||||
}
|
||||
}
|
||||
|
||||
return string("update_addresses_of_interface ") +
|
||||
"\"" +
|
||||
arg1.join(" ").toStdString() +
|
||||
"\"" +
|
||||
" \"\"";
|
||||
}
|
||||
|
||||
|
||||
void OSConfigurator_bsd::addVirtualAddressForNAT(const Network*)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from NATCompiler_pf::addVirtualAddress::processNext()
|
||||
*/
|
||||
void OSConfigurator_bsd::addVirtualAddressForNAT(const Address *addr)
|
||||
{
|
||||
if (virtual_addresses.empty() ||
|
||||
find(virtual_addresses.begin(),
|
||||
virtual_addresses.end(),
|
||||
*(addr->getAddressPtr())) == virtual_addresses.end())
|
||||
FWObject *iaddr = findAddressFor(addr, fw );
|
||||
if (iaddr!=NULL)
|
||||
{
|
||||
FWObject *iaddr = findAddressFor(addr, fw );
|
||||
if (iaddr!=NULL)
|
||||
{
|
||||
Address *iaddr_addr = Address::cast(iaddr);
|
||||
assert(iaddr_addr!=NULL);
|
||||
const InetAddr *ipaddr = iaddr_addr->getAddressPtr();
|
||||
const InetAddr *ipnetm = iaddr_addr->getNetmaskPtr();
|
||||
|
||||
Interface *iface = Interface::cast(iaddr->getParent());
|
||||
assert(iface!=NULL);
|
||||
|
||||
if (ipaddr->isV6())
|
||||
{
|
||||
output << "add_addr6 " << addr->getAddressPtr()->toString() << " "
|
||||
<< ipnetm->getLength() << " "
|
||||
<< iface->getName() << endl;
|
||||
} else
|
||||
{
|
||||
output << "add_addr " << addr->getAddressPtr()->toString() << " "
|
||||
<< ipnetm->toString() << " "
|
||||
<< iface->getName() << endl;
|
||||
}
|
||||
|
||||
virtual_addresses.push_back(*(addr->getAddressPtr()));
|
||||
} else
|
||||
warning("Can not add virtual address " +
|
||||
addr->getAddressPtr()->toString() );
|
||||
}
|
||||
virtual_addresses.insert(addr);
|
||||
} else
|
||||
warning("Can not add virtual address " +
|
||||
addr->getAddressPtr()->toString() );
|
||||
}
|
||||
|
||||
int OSConfigurator_bsd::prolog()
|
||||
@ -107,6 +135,8 @@ int OSConfigurator_bsd::prolog()
|
||||
|
||||
string OSConfigurator_bsd::printFunctions()
|
||||
{
|
||||
ostringstream ostr;
|
||||
|
||||
FWOptions* options=fw->getOptionsObject();
|
||||
|
||||
Configlet functions(fw, "bsd", "shell_functions");
|
||||
@ -144,7 +174,16 @@ string OSConfigurator_bsd::printFunctions()
|
||||
} else
|
||||
functions.setVariable("get_dyn_addr_commands", "");
|
||||
|
||||
return functions.expand().toStdString();
|
||||
ostr << functions.expand().toStdString();
|
||||
|
||||
if ( options->getBool("configure_interfaces") )
|
||||
{
|
||||
Configlet update_addresses(fw, "bsd", "update_addresses");
|
||||
update_addresses.removeComments();
|
||||
ostr << update_addresses.expand().toStdString();
|
||||
}
|
||||
|
||||
return ostr.str();
|
||||
}
|
||||
|
||||
string OSConfigurator_bsd::configureInterfaces()
|
||||
@ -169,30 +208,39 @@ string OSConfigurator_bsd::configureInterfaces()
|
||||
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 *iaddr = Address::cast(*j);
|
||||
|
||||
const InetAddr *ipaddr = iaddr->getAddressPtr();
|
||||
const InetAddr *ipnetm = iaddr->getNetmaskPtr();
|
||||
|
||||
if (ipaddr->isV6())
|
||||
{
|
||||
ostr << "add_addr6 "
|
||||
<< ipaddr->toString() << " "
|
||||
<< ipnetm->getLength() << " "
|
||||
<< iface->getName() << endl;
|
||||
} else
|
||||
{
|
||||
ostr << "add_addr "
|
||||
<< ipaddr->toString() << " "
|
||||
<< ipnetm->toString() << " "
|
||||
<< iface->getName() << endl;
|
||||
}
|
||||
|
||||
virtual_addresses.push_back(*ipaddr);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -30,6 +30,8 @@
|
||||
|
||||
#include "fwcompiler/OSConfigurator.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
#include <QString>
|
||||
|
||||
|
||||
@ -41,11 +43,15 @@ namespace fwcompiler {
|
||||
class OSConfigurator_bsd : public OSConfigurator {
|
||||
|
||||
protected:
|
||||
std::vector<libfwbuilder::InetAddr> virtual_addresses;
|
||||
std::set<const libfwbuilder::Address*> virtual_addresses;
|
||||
|
||||
void setKernelVariable(libfwbuilder::Firewall *fw,
|
||||
const std::string &var_name,
|
||||
Configlet *configlet);
|
||||
std::string updateAddressesOfInterfaceCall(
|
||||
libfwbuilder::Interface *iface,
|
||||
std::list<std::pair<libfwbuilder::InetAddr,libfwbuilder::InetAddr> > all_addresses);
|
||||
|
||||
public:
|
||||
|
||||
virtual ~OSConfigurator_bsd() {};
|
||||
|
||||
@ -16,26 +16,18 @@ log() {
|
||||
test -x "$LOGGER" && $LOGGER -p info "$1"
|
||||
}
|
||||
|
||||
add_addr() {
|
||||
addr=$1
|
||||
nm=$2
|
||||
dev=$3
|
||||
( ifconfig $dev | egrep -q "inet +${addr} " ) ||
|
||||
{
|
||||
echo "$dev: $addr/$nm"
|
||||
ifconfig $dev inet $addr netmask $nm alias
|
||||
}
|
||||
}
|
||||
|
||||
add_addr6() {
|
||||
addr=$1
|
||||
nm=$2
|
||||
dev=$3
|
||||
( ifconfig $dev | egrep -q "inet6 +${addr} " ) ||
|
||||
{
|
||||
echo "$dev: $addr/$nm"
|
||||
ifconfig $dev inet6 $addr prefixlen $nm alias
|
||||
}
|
||||
diff_intf() {
|
||||
func=$1
|
||||
list1=$2
|
||||
list2=$3
|
||||
cmd=$4
|
||||
for intf in $list1
|
||||
do
|
||||
echo $list2 | grep -q $intf || {
|
||||
# $vlan is absent in list 2
|
||||
$func $intf $cmd
|
||||
}
|
||||
done
|
||||
}
|
||||
|
||||
{{if dyn_addr}}
|
||||
|
||||
119
src/res/configlets/bsd/update_addresses
Normal file
119
src/res/configlets/bsd/update_addresses
Normal file
@ -0,0 +1,119 @@
|
||||
## -*- 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.
|
||||
##
|
||||
############ add or remove ip addresses of interfaces #######################
|
||||
|
||||
## address (argument 1) is in the form of address/netmask, where
|
||||
## netmask should be hex represenatation matching netmask in the
|
||||
## output of ifconfig for ipv4 address. For ipv6 addresses netmask
|
||||
## part should be given as prefix length.
|
||||
missing_address() {
|
||||
address=$1
|
||||
cmd=$2
|
||||
|
||||
oldIFS=$IFS
|
||||
IFS="@"
|
||||
set $address
|
||||
addr=$1
|
||||
interface=$2
|
||||
IFS=$oldIFS
|
||||
|
||||
if echo "$addr" | grep -q ':'
|
||||
then
|
||||
inet="inet6"
|
||||
addr=$(echo "$addr" | sed 's!/! prefixlen !')
|
||||
else
|
||||
inet="inet"
|
||||
addr=$(echo "$addr" | sed 's!/! netmask !')
|
||||
fi
|
||||
|
||||
parameter=""
|
||||
test "$cmd" = "add" && {
|
||||
echo "# Adding ip address: $interface $addr"
|
||||
parameter="alias"
|
||||
}
|
||||
test "$cmd" = "del" && {
|
||||
echo "# Removing ip address: $interface $addr"
|
||||
parameter="delete"
|
||||
}
|
||||
|
||||
$FWBDEBUG $IFCONFIG $interface $inet $addr $parameter
|
||||
$FWBDEBUG $IFCONFIG $interface up
|
||||
}
|
||||
|
||||
##
|
||||
## The list of current addresses is taken using "ifconfig $interface"
|
||||
## command. Second argument defines address scrope; it should be in
|
||||
## the form of the matching regex such as "scope global" or "scope
|
||||
## .*". Unfortunately ifconfig prints "scopeid" for link and host
|
||||
## scopes but does not print any "scopeid" parameter for the global
|
||||
## scope (tested on OpenBSD 4.2). This means I have to invert the
|
||||
## regex match logic and skip addresses with given scope (this is
|
||||
## different from how this function works for addresses on Linux). If
|
||||
## any non-empty scope string is given as second argument, this
|
||||
## function will skip addresses with this scope. If this argument is
|
||||
## an empty string, this function returns all addresses.
|
||||
##
|
||||
list_addresses_by_scope() {
|
||||
interface=$1
|
||||
scope=$2
|
||||
ignore_list=$3
|
||||
|
||||
scope_regex="1"
|
||||
if test -n "$scope"; then scope_regex=" \$0 !~ \"$scope\" "; fi
|
||||
|
||||
$IFCONFIG $interface | sed "s/%$interface//" | \
|
||||
awk -v IGNORED="$ignore_list" \
|
||||
"BEGIN {
|
||||
split(IGNORED,ignored_arr);
|
||||
for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;}
|
||||
}
|
||||
(/inet |inet6 / && $scope_regex && !(\$2 in ignored_dict)) {printf \"%s/%s\n\",\$2,\$4;}" | \
|
||||
while read addr; do
|
||||
echo "${addr}@$interface"
|
||||
done | sort
|
||||
|
||||
}
|
||||
|
||||
## arg 1 is like "pcn1 1.1.1.1/24 2.2.2.2/24 fe80::20c:29ff:fef6:bea0/64"
|
||||
## arg 2 is "3.3.3.3/24 4.4.4.4/24" - list of addresses we should ignore
|
||||
## Using arg2 to provide list of addresses managed by heartbeat, so that
|
||||
## incremental update does not delete them.
|
||||
##
|
||||
## Only "scope global" addreses are managed because fwbuilder script
|
||||
## should not try to delete addresses configured for tunnels and IPv6
|
||||
## link scope addresses (fe80::) ("scope link" or "scope host" addresses)
|
||||
##
|
||||
## Addresses we should ignore are dropped from the list.
|
||||
##
|
||||
update_addresses_of_interface() {
|
||||
ignore_list=$2
|
||||
set $1
|
||||
interface=$1
|
||||
shift
|
||||
|
||||
FWB_ADDRS=$(
|
||||
for addr in $*; do
|
||||
echo "${addr}@$interface"
|
||||
done | sort
|
||||
)
|
||||
|
||||
CURRENT_ADDRS_ALL_SCOPES=""
|
||||
CURRENT_ADDRS_GLOBAL_SCOPE=""
|
||||
|
||||
$IFCONFIG $interface >/dev/null 2>&1 && {
|
||||
CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface '' "$ignore_list")
|
||||
CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scopeid .*' "$ignore_list")
|
||||
} || {
|
||||
echo "# Interface $interface does not exist"
|
||||
# Stop the script if we are not in test mode
|
||||
test -z "$FWBDEBUG" && exit 1
|
||||
}
|
||||
|
||||
diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add
|
||||
diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
##
|
||||
## Set path to all utilities that we need
|
||||
|
||||
IFCONFIG="ifconfig"
|
||||
PFCTL="{{$path_pfctl}}"
|
||||
SYSCTL="{{$path_sysctl}}"
|
||||
LOGGER="{{$path_logger}}"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user