Merge pull request #1962 from davidjwood/RELENG_2_2-ppp-ipv6

This commit is contained in:
Chris Buechler 2015-10-12 19:10:32 -05:00
commit 94b89bdf07
3 changed files with 170 additions and 34 deletions

123
usr/local/sbin/ppp-ipv6 Executable file
View File

@ -0,0 +1,123 @@
#!/usr/local/bin/php -f
<?php
/*
ppp-ipv6
PPP IPv6 helper
pfSense_BUILDER_BINARIES: /sbin/ifconfig /usr/local/sbin/dhcp6c
*/
require_once("globals.inc");
require_once("interfaces.inc");
function interface_ipv6_lower($interface_real) {
global $g, $config;
if (!empty($interface_real)) {
$interface = convert_real_interface_to_friendly_interface_name($interface_real);
if (!empty($interface) && is_array($config['interfaces'][$interface]) && interface_isppp_type($interface)) {
$ifcfg = $config['interfaces'][$interface];
if (!empty($ifcfg['ipaddrv6'])) {
switch ($ifcfg['ipaddrv6']) {
case 'slaac':
case 'dhcp6':
// bring down dhcp6c if it is running
$pidv6 = find_dhcp6c_process($interface_real);
if ($pidv6) {
posix_kill($pidv6, SIGTERM);
sleep(3);
}
unlink_if_exists("{$g['varetc_path']}/dhcp6c_{$interface}.conf");
// disable router advertisements (and therefore SLAAC)
mwexec("/sbin/ifconfig " . escapeshellarg($interface_real) . " inet6 -accept_rtadv");
// remove any autoconfigured IPv6 addresses
exec("/sbin/ifconfig " . escapeshellarg($interface_real) . " inet6", $ifconfig_output);
foreach ($ifconfig_output as $output) {
if (preg_match('{ \A \s+ inet6 \s+ (\S+) .* autoconf .* \Z}xmsi', $output, $matches)) {
mwexec("/sbin/ifconfig " . escapeshellarg($interface_real) . " inet6 " . escapeshellarg($matches[1]) . " delete");
}
}
break;
default:
break;
}
}
}
}
}
function interface_ipv6_raise($interface_real) {
global $config;
if (!empty($interface_real)) {
$interface = convert_real_interface_to_friendly_interface_name($interface_real);
if (!empty($interface) && is_array($config['interfaces'][$interface]) && interface_isppp_type($interface)) {
$ifcfg = $config['interfaces'][$interface];
if (!empty($ifcfg['ipaddrv6'])) {
switch ($ifcfg['ipaddrv6']) {
case 'slaac':
case 'dhcp6':
$pidv6 = find_dhcp6c_process($interface_real);
if (empty($pidv6)) {
// only fire if router advertisements off
// (if router advertisements are on, rtsold might be primed to fire dhcp6c already)
exec("/sbin/ifconfig " . escapeshellarg($interface_real) . " inet6", $ifconfig_output);
$start = true;
foreach ($ifconfig_output as $output) {
if (preg_match('{ \A .* ACCEPT_RTADV .* \Z}xmsi', $output)) {
$start = false;
break;
}
}
if ($start) {
interface_dhcpv6_configure($interface, $ifcfg);
}
}
break;
default:
break;
}
}
}
}
}
// main entry point
if ($argc != 3) {
goto error;
}
$interface_real = trim($argv[1], " \n\t");
if (empty($interface_real)) {
goto error;
}
switch (strtolower($argv[2])) {
case 'up':
interface_ipv6_raise($interface_real);
break;
case 'down':
interface_ipv6_lower($interface_real);
break;
default:
goto error;
break;
}
exit(0);
error:
if (!empty($argv[0])) {
echo("Usage: " . substr(strrchr('/' . $argv[0], '/'), 1) . " <PPP interface> up|down\n");
}
exit(1);
?>

View File

@ -1,6 +1,7 @@
#!/bin/sh
IF="${1}"
PROTOCOL="${2}"
LOCAL_IP="${3}"
if [ -f /tmp/${IF}up ] && [ -f /conf/${IF}.log ]; then
@ -10,17 +11,20 @@ fi
/etc/rc.kill_states ${IF} ${LOCAL_IP}
if [ -s "/tmp/${IF}_defaultgw" ]; then
if [ "${PROTOCOL}" == "inet" && -s "/tmp/${IF}_defaultgw" ]; then
GW=`head -n 1 /tmp/${IF}_defaultgw`
[ -n "${GW}" ] \
&& /sbin/route delete default ${GW}
&& /sbin/route -q delete default ${GW}
fi
if [ "${PROTOCOL}" == "inet6" ]; then
/usr/local/sbin/ppp-ipv6 ${IF} down
fi
# delete the node just in case mpd cannot do that
/usr/sbin/ngctl shutdown ${IF}:
if [ -f "/var/etc/nameserver_${IF}" ]; then
# Remove old entries
for nameserver in `cat /var/etc/nameserver_${IF}`; do
/sbin/route delete ${nameserver} >/dev/null 2>&1
/sbin/route -q delete ${nameserver} >/dev/null 2>&1
done
/bin/rm -f /var/etc/nameserver_${IF}
fi

View File

@ -2,61 +2,70 @@
export PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin
if [ "${2}" == "inet" ]; then
IF="${1}"
PROTOCOL="${2}"
LOCAL_IP="${3}"
REMOTE_IP="${4}"
AUTH_NAME="${5}"
DNS1_RAW="${6}"
DNS2_RAW="${7}"
OLD_ROUTER=`cat /tmp/${1}_router`
if [ "${PROTOCOL}" == "inet" ]; then
OLD_ROUTER=`cat /tmp/${IF}_router`
if [ -n "${OLD_ROUTER}" ]; then
echo "Removing states to old router ${OLD_ROUTER}" | logger -t ppp-linkup
pfctl -i ${1} -k 0.0.0.0/0 -k ${OLD_ROUTER}/32
pfctl -i ${1} -k ${OLD_ROUTER}/32 -k 0.0.0.0/0
pfctl -i ${IF} -k 0.0.0.0/0 -k ${OLD_ROUTER}/32
pfctl -i ${IF} -k ${OLD_ROUTER}/32 -k 0.0.0.0/0
fi
# let the configuration system know that the ipv4 has changed.
echo ${4} > /tmp/${1}_router
echo ${3} > /tmp/${1}_ip
touch /tmp/${1}up
echo ${REMOTE_IP} > /tmp/${IF}_router
echo ${LOCAL_IP} > /tmp/${IF}_ip
touch /tmp/${IF}up
if grep -q dnsallowoverride /conf/config.xml; then
# write nameservers to file
echo -n "" > /var/etc/nameserver_${1}
if echo "${6}" | grep -q dns1; then
DNS1=`echo "${6}" | awk '{print $2}'`
echo "${DNS1}" >> /var/etc/nameserver_${1}
route change "${DNS1}" ${4}
echo -n "" > /var/etc/nameserver_${IF}
if echo "${DNS1_RAW}" | grep -q dns1; then
DNS1=`echo "${DNS1_RAW}" | awk '{print $2}'`
echo "${DNS1}" >> /var/etc/nameserver_${IF}
route change "${DNS1}" ${REMOTE_IP}
fi
if echo "${7}" | grep -q dns2; then
DNS2=`echo "${7}" | awk '{print $2}'`
echo "${DNS2}" >> /var/etc/nameserver_${1}
route change "${DNS2}" ${4}
if echo "${DNS2_RAW}" | grep -q dns2; then
DNS2=`echo "${DNS2_RAW}" | awk '{print $2}'`
echo "${DNS2}" >> /var/etc/nameserver_${IF}
route change "${DNS2}" ${REMOTE_IP}
fi
pfSctl -c 'service reload dns'
sleep 1
fi
pfSctl -c "interface newip ${1}"
pfSctl -c "interface newip ${IF}"
elif [ "${2}" == "inet6" ]; then
elif [ "${PROTOCOL}" == "inet6" ]; then
/usr/local/sbin/ppp-ipv6 ${IF} up
# let the configuration system know that the ipv6 has changed.
echo ${4} |cut -d% -f1 > /tmp/${1}_routerv6
echo ${3} |cut -d% -f1 > /tmp/${1}_ipv6
touch /tmp/${1}upv6
echo ${REMOTE_IP} |cut -d% -f1 > /tmp/${IF}_routerv6
echo ${LOCAL_IP} |cut -d% -f1 > /tmp/${IF}_ipv6
touch /tmp/${IF}upv6
if grep -q dnsallowoverride /conf/config.xml; then
# write nameservers to file
echo -n "" > /var/etc/nameserver_v6${1}
if echo "${6}" | grep -q dns1; then
DNS1=`echo "${6}" | awk '{print $2}'`
echo "${DNS1}" >> /var/etc/nameserver_v6${1}
route change -inet6 "${DNS1}" ${4}
echo -n "" > /var/etc/nameserver_v6${IF}
if echo "${DNS1_RAW}" | grep -q dns1; then
DNS1=`echo "${DNS1_RAW}" | awk '{print $2}'`
echo "${DNS1}" >> /var/etc/nameserver_v6${IF}
route change -inet6 "${DNS1}" ${REMOTE_IP}
fi
if echo "${7}" | grep -q dns2; then
DNS2=`echo "${7}" | awk '{print $2}'`
echo "${DNS2}" >> /var/etc/nameserver_v6${1}
route change -inet6 "${DNS2}" ${4}
if echo "${DNS2_RAW}" | grep -q dns2; then
DNS2=`echo "${DNS2_RAW}" | awk '{print $2}'`
echo "${DNS2}" >> /var/etc/nameserver_v6${IF}
route change -inet6 "${DNS2}" ${REMOTE_IP}
fi
pfSctl -c 'service reload dns'
sleep 1
fi
pfSctl -c "interface newipv6 ${1}"
pfSctl -c "interface newipv6 ${IF}"
fi
exit 0