interfaces: widen and improve ifctl use

We do want to eventually lean on exclusive ifctl use in order to
be able to improve logic in ifctl or make adjustments really easy in
the future without missing a spot (e.g. adding scope to link-local
routers).
This commit is contained in:
Franco Fichtner 2022-07-22 10:54:55 +02:00
parent d582435b4b
commit 90db8f4d0f
4 changed files with 100 additions and 54 deletions

View File

@ -932,13 +932,8 @@ function interface_bring_down($interface = "wan", $ifacecfg = false)
}
/* clear stale state files associated with this interface */
@unlink("/tmp/{$realifv6}_nameserverv6");
@unlink("/tmp/{$realifv6}_prefixv6");
@unlink("/tmp/{$realifv6}_routerv6");
@unlink("/tmp/{$realifv6}_searchdomainv6");
@unlink("/tmp/{$realif}_nameserver");
@unlink("/tmp/{$realif}_router");
@unlink("/tmp/{$realif}_searchdomain");
mwexecf('/usr/local/sbin/ifctl -4c -i %s', $realif);
mwexecf('/usr/local/sbin/ifctl -6c -i %s', $realifv6);
}
function interfaces_ptpid_used($ptpid)
@ -3930,8 +3925,7 @@ function get_interfaces_info($include_unlinked = false)
}
}
/* XXX there are more magic files */
$aux = @file_get_contents("/tmp/{$ifinfo['ifv6']}_prefixv6");
$aux = trim(shell_exec(exec_safe('/usr/local/sbin/ifctl -6pi %s', $ifinfo['ifv6'])));
if (!empty($aux)) {
$ifinfo['prefixv6'] = $aux;
}

View File

@ -294,13 +294,16 @@ function get_zoneinfo()
function get_searchdomains()
{
$search_list = glob('/tmp/*_searchdomain*');
$syscfg = config_read_array('system');
$master_list = [];
$search_list = [];
if (!isset($syscfg['dnsallowoverride'])) {
/* do not return domains as required by configuration */
$search_list = [];
if (isset($syscfg['dnsallowoverride'])) {
/* return domains as required by configuration */
$list = trim(shell_exec('/usr/local/sbin/ifctl -sl'));
if (!empty($list)) {
$search_list = explode("\n", $list);
}
}
if (is_array($search_list)) {
@ -325,22 +328,29 @@ function get_nameservers($interface = null, $with_gateway = false)
global $config;
$gateways = new \OPNsense\Routing\Gateways(legacy_interfaces_details());
$dns_lists = glob('/tmp/*_nameserver*');
$syscfg = config_read_array('system');
$exclude_interfaces = [];
$master_list = [];
$dns_lists = [];
if (!empty($interface)) {
/* only acquire servers provided for this interface */
$realif = get_real_interface($interface);
$realifv6 = get_real_interface($interface, 'inet6');
$dns_lists = [
"/tmp/{$realif}_nameserver",
"/tmp/{$realifv6}_nameserverv6",
];
} elseif (!isset($syscfg['dnsallowoverride'])) {
/* do not return dynamic servers as required by configuration */
$dns_lists = [];
$list = trim(shell_exec(exec_safe('/usr/local/sbin/ifctl -4nli %s', $realif)));
if (!empty($list)) {
$dns_lists[] = $list;
}
$list = trim(shell_exec(exec_safe('/usr/local/sbin/ifctl -6nli %s', $realifv6)));
if (!empty($list)) {
$dns_lists[] = $list;
}
} elseif (isset($syscfg['dnsallowoverride'])) {
/* return dynamic servers as required by configuration */
$list = trim(shell_exec('/usr/local/sbin/ifctl -nl'));
if (!empty($list)) {
$dns_lists = explode("\n", $list);
}
}
if (isset($syscfg['dnsallowoverride_exclude'])) {
@ -355,7 +365,8 @@ function get_nameservers($interface = null, $with_gateway = false)
foreach ($dns_lists as $fdns) {
/* inspect dynamic servers registered in the system files */
$intf = explode('_', basename($fdns))[0];
$intf = explode('_', basename($fdns), 2);
$intf[1] = strpos($intf[1], 'v6') === false ? '4' : '6';
if (in_array($intf, $exclude_interfaces)) {
continue;
}
@ -365,10 +376,12 @@ function get_nameservers($interface = null, $with_gateway = false)
continue;
}
/* router file is available for connectivity creating nameserver files */
$gw = trim(@file_get_contents(str_replace('_nameserver', '_router', $fdns)));
if (is_linklocal($gw) && strpos($gw, '%') === false) {
$gw .= "%{$intf}";
if ($with_gateway) {
/* router file is available for connectivity creating nameserver files */
$gw = trim(shell_exec(exec_safe('/usr/local/sbin/ifctl -%s -ri %s', [$intf[1], $intf[0]])));
if (is_linklocal($gw) && strpos($gw, '%') === false) {
$gw .= "%{$intf[0]}";
}
}
foreach ($contents as $dns) {

View File

@ -24,7 +24,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd March 18, 2022
.Dd July 22, 2022
.Dt IFCTL 8
.Os
.Sh NAME
@ -33,15 +33,16 @@
.Sh SYNOPSIS
.Nm
.Op Fl i Ar device
.Op Fl 46
.Op Fl nprs
.Op Fl d
.Op Fl a Ar data
.Op Fl a Ar data | Fl c | Fl d | Fl l
.Sh DESCRIPTION
The
.Nm
utility will display or modify network device related data used by dynamic
connections.
If neither
If one of
.Sq Fl c ,
.Sq Fl d
or
.Sq Fl a
@ -55,14 +56,16 @@ This is the default.
.It Fl 6
Use IPv6 mode.
.It Fl a
Append data to the currently selected device information.
Append data to the currently selected device data.
The option can be used multiple times in the same command invoke
to append data at once.
Note that
.Sq Fl d
will be executed first when given in the same command invoke.
.It Fl c
Clear all registed data of the selected device.
.It Fl d
Delete the data of the currently selected device information.
Delete the specified data of the selected device.
.It Fl i Ar device
Select the
.Ar device
@ -70,6 +73,11 @@ to operate on.
If none was given
.Nm
list the available devices.
.It Fl l
List mode turns the output into the storage files available for reading.
For implementational reasons the address family selector is ignored when
not using the interface option
.Sq Fl i .
.It Fl n
Use name server mode.
This is the default.

View File

@ -23,9 +23,8 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
DO_COMMAND=
DO_CONTENTS=
DO_DELETE=
DO_MODE=
DO_VERBOSE=
AF=
@ -33,10 +32,22 @@ MD=
EX=
IF=
flush_routes()
{
if [ "${MD}" != "nameserver" -o ! -f "${FILE}" ]; then
return
fi
for CONTENT in $(cat ${FILE}); do
# flush routes here to make sure they are recycled properly
route delete -${AF} "${CONTENT}"
done
}
# default to IPv4 with nameserver mode
set -- -4 -n ${@}
while getopts 46a:di:nprsV OPT; do
while getopts 46a:cdi:lnprsV OPT; do
case ${OPT} in
4)
AF=inet
@ -47,28 +58,31 @@ while getopts 46a:di:nprsV OPT; do
EX=v6
;;
a)
DO_COMMAND="-a"
DO_CONTENTS="${DO_CONTENTS} ${OPTARG}"
;;
c)
MD="nameserver prefix router searchdomain"
;;
d)
DO_DELETE="-d"
DO_COMMAND="-d"
;;
i)
IF=${OPTARG}
;;
l)
DO_COMMAND="-l"
;;
n)
DO_MODE="-n"
MD="nameserver"
;;
p)
DO_MODE="-p"
MD="prefix"
;;
r)
DO_MODE="-r"
MD="router"
;;
s)
DO_MODE="-s"
MD="searchdomain"
;;
V)
@ -85,6 +99,29 @@ if [ -n "${DO_VERBOSE}" ]; then
set -x
fi
if [ "${DO_COMMAND}" = "-c" ]; then
if [ -z "${IF}" ]; then
echo "Clearing requires interface option" >&2
exit 1
fi
# iterate through possible files
for MD in nameserver prefix router searchdomain; do
FILE="/tmp/${IF}_${MD}${EX}"
flush_routes
rm -f ${FILE}
done
exit 0
elif [ "${DO_COMMAND}" = "-l" ]; then
if [ -z "${IF}" ]; then
EX="*"
IF="*"
fi
find -s /tmp -name "${IF}_${MD}${EX}"
exit 0
fi
FILE="/tmp/${IF:-*}_${MD}${EX}"
if [ -z "${IF}" ]; then
@ -98,20 +135,14 @@ if [ -z "${IF}" ]; then
exit 0
fi
if [ -n "${DO_DELETE}" ]; then
if [ "${DO_MODE}" = "-n" -a -f ${FILE} ]; then
for CONTENT in $(cat ${FILE}); do
# flush routes here to make sure they are recycled properly
route delete -${AF} "${CONTENT}"
done
fi
if [ "${DO_COMMAND}" = "-d" ]; then
flush_routes
rm -f ${FILE}
fi
for CONTENT in ${DO_CONTENTS}; do
echo "${CONTENT}" >> ${FILE}
done
if [ -z "${DO_CONTENTS}${DO_DELETE}" -a -f ${FILE} ]; then
elif [ "${DO_COMMAND}" = "-a" ]; then
for CONTENT in ${DO_CONTENTS}; do
echo "${CONTENT}" >> ${FILE}
done
# if nothing else could be done display data
elif [ -f ${FILE} ]; then
cat ${FILE}
fi