Implement IPv6 proxyndp

This commit is contained in:
Tom Eastep 2010-12-10 19:06:44 -08:00
parent 2ae809888c
commit caa4a54e38
5 changed files with 102 additions and 78 deletions

View File

@ -388,7 +388,11 @@ sub generate_script_3($) {
'' );
save_dynamic_chains;
mark_firewall_not_started;
emit '';
emit ('',
'delete_proxyndp',
''
);
}
emit qq(delete_tc1\n) if $config{CLEAR_TC};
@ -397,7 +401,12 @@ sub generate_script_3($) {
emit( 'setup_routing_and_traffic_shaping', '' );
emit 'cat > ${VARDIR}/proxyarp << __EOF__';
if ( $family == F_IPV4 ) {
emit 'cat > ${VARDIR}/proxyarp << __EOF__';
} else {
emit 'cat > ${VARDIR}/proxyndp << __EOF__';
}
dump_proxy_arp;
emit_unindented '__EOF__';

View File

@ -59,6 +59,8 @@ sub initialize( $ ) {
sub setup_one_proxy_arp( $$$$$$$ ) {
my ( $address, $interface, $physical, $external, $extphy, $haveroute, $persistent) = @_;
my $proto = $family == F_IPV4 ? 'ARP' : 'NDP';
if ( "\L$haveroute" eq 'no' || $haveroute eq '-' ) {
$haveroute = '';
} elsif ( "\L$haveroute" eq 'yes' ) {
@ -76,107 +78,91 @@ sub setup_one_proxy_arp( $$$$$$$ ) {
}
unless ( $haveroute ) {
emit "[ -n \"\$g_noroutes\" ] || run_ip route replace $address dev $physical";
if ( $family == F_IPV4 ) {
emit "[ -n \"\$g_noroutes\" ] || run_ip route replace $address/32 dev $physical";
} else {
emit "[ -n \"\$g_noroutes\" ] || run_ip route replace $address/128 dev $physical";
}
$haveroute = 1 if $persistent;
}
emit ( "if ! arp -i $extphy -Ds $address $extphy pub; then",
" fatal_error \"Command 'arp -i $extphy -Ds $address $extphy pub' failed\"" ,
'fi' ,
'',
"progress_message \" Host $address connected to $interface added to ARP on $extphy\"\n" );
emit ( "run_ip neigh add proxy $address nud permanent dev $extphy" ,
qq(progress_message " Host $address connected to $interface added to $proto on $extphy"\n) );
push @proxyarp, "$address $interface $external $haveroute";
progress_message " Host $address connected to $interface added to ARP on $external";
progress_message " Host $address connected to $interface added to $proto on $external";
}
#
# Setup Proxy ARP
# Setup Proxy ARP/NDP
#
sub setup_proxy_arp() {
if ( $family == F_IPV4 ) {
my $proto = $family == F_IPV4 ? 'arp' : 'ndp'; # Protocol
my $file_opt = 'proxy' . $proto; # Name of config file and of the interface option
my $proc_file = 'proxy_' . $proto; # Name of the corresponding file in /proc
my $interfaces= find_interfaces_by_option 'proxyarp';
my $fn = open_file 'proxyarp';
my $interfaces= find_interfaces_by_option $file_opt;
my $fn = open_file $file_opt;
if ( @$interfaces || $fn ) {
if ( @$interfaces || $fn ) {
my $first_entry = 1;
my $first_entry = 1;
save_progress_message "Setting up Proxy ARP...";
save_progress_message 'Setting up Proxy ' . uc($proto) . '...';
my ( %set, %reset );
my ( %set, %reset );
while ( read_a_line ) {
while ( read_a_line ) {
my ( $address, $interface, $external, $haveroute, $persistent ) = split_line 3, 5, 'proxyarp file';
my ( $address, $interface, $external, $haveroute, $persistent ) = split_line 3, 5, 'proxyarp file';
if ( $first_entry ) {
progress_message2 "$doing $fn...";
$first_entry = 0;
}
my $physical = physical_name $interface;
my $extphy = physical_name $external;
$set{$interface} = 1;
$reset{$external} = 1 unless $set{$external};
setup_one_proxy_arp( $address, $interface, $physical, $external, $extphy, $haveroute, $persistent );
if ( $first_entry ) {
progress_message2 "$doing $fn...";
$first_entry = 0;
}
emit '';
my $physical = physical_name $interface;
my $extphy = physical_name $external;
for my $interface ( keys %reset ) {
unless ( $set{interface} ) {
my $physical = get_physical $interface;
emit ( "if [ -f /proc/sys/net/ipv4/conf/$physical/proxy_arp ]; then" ,
" echo 0 > /proc/sys/net/ipv4/conf/$physical/proxy_arp" );
emit "fi\n";
}
}
$set{$interface} = 1;
$reset{$external} = 1 unless $set{$external};
for my $interface ( keys %set ) {
setup_one_proxy_arp( $address, $interface, $physical, $external, $extphy, $haveroute, $persistent );
}
emit '';
for my $interface ( keys %reset ) {
unless ( $set{interface} ) {
my $physical = get_physical $interface;
emit ( "if [ -f /proc/sys/net/ipv4/conf/$physical/proxy_arp ]; then" ,
" echo 1 > /proc/sys/net/ipv4/conf/$physical/proxy_arp" );
emit ( 'else' ,
" error_message \" WARNING: Cannot set the 'proxy_arp' option for interface $physical\"" ) unless interface_is_optional( $interface );
emit ( "if [ -f /proc/sys/net/ipv$family/conf/$physical/$proc_file ]; then" ,
" echo 0 > /proc/sys/net/ipv$family/conf/$physical/$proc_file" );
emit "fi\n";
}
for my $interface ( @$interfaces ) {
my $value = get_interface_option $interface, 'proxyarp';
my $optional = interface_is_optional $interface;
$interface = get_physical $interface;
emit ( "if [ -f /proc/sys/net/ipv4/conf/$interface/proxy_arp ] ; then" ,
" echo $value > /proc/sys/net/ipv4/conf/$interface/proxy_arp" );
emit ( 'else' ,
" error_message \"WARNING: Unable to set/reset proxy ARP on $interface\"" ) unless $optional;
emit "fi\n";
}
}
} else {
my $interfaces= find_interfaces_by_option 'proxyndp';
if ( @$interfaces ) {
save_progress_message "Setting up Proxy NDP...";
for my $interface ( keys %set ) {
my $physical = get_physical $interface;
emit ( "if [ -f /proc/sys/net/ipv$family/conf/$physical/$proc_file ]; then" ,
" echo 1 > /proc/sys/net/ipv$family/conf/$physical/$proc_file" );
emit ( 'else' ,
" error_message \" WARNING: Cannot set the '$file_opt' option for interface $physical\"" ) unless interface_is_optional( $interface );
emit "fi\n";
}
for my $interface ( @$interfaces ) {
my $value = get_interface_option $interface, 'proxyndp';
my $optional = interface_is_optional $interface;
for my $interface ( @$interfaces ) {
my $value = get_interface_option $interface, $file_opt;
my $optional = interface_is_optional $interface;
$interface = get_physical $interface;
$interface = get_physical $interface;
emit ( "if [ -f /proc/sys/net/ipv6/conf/$interface/proxy_ndp ] ; then" ,
" echo $value > /proc/sys/net/ipv6/conf/$interface/proxy_ndp" );
emit ( 'else' ,
" error_message \"WARNING: Unable to set/reset Proxy NDP on $interface\"" ) unless $optional;
emit "fi\n";
}
emit ( "if [ -f /proc/sys/net/ipv$family/conf/$interface/$proc_file ] ; then" ,
" echo $value > /proc/sys/net/ipv$family/conf/$interface/$proc_file" );
emit ( 'else' ,
" error_message \"WARNING: Unable to set/reset the '$file_opt' option on $interface\"" ) unless $optional;
emit "fi\n";
}
}
}

View File

@ -2520,8 +2520,8 @@ EOF
emit <<'EOF';
if [ -f ${VARDIR}/proxyarp ]; then
while read address interface external haveroute; do
qt arp -i $external -d $address pub
[ -z "${haveroute}${g_noroutes}" ] && qt $IP -4 route del $address dev $interface
qt $IP -4 neigh del proxy $address dev $external
[ -z "${haveroute}${g_noroutes}" ] && qt $IP -4 route del $address/32 dev $interface
f=/proc/sys/net/ipv4/conf/$interface/proxy_arp
[ -f $f ] && echo 0 > $f
done < ${VARDIR}/proxyarp
@ -2530,7 +2530,20 @@ EOF
fi
EOF
}
} else {
emit <<'EOF';
if [ -f ${VARDIR}/proxyndp ]; then
while read address interface external haveroute; do
qt $IP -6 neigh del proxy $address dev $external
[ -z "${haveroute}${g_noroutes}" ] && qt $IP -6 route del $address/128 dev $interface
f=/proc/sys/net/ipv4/conf/$interface/proxy_ndp
[ -f $f ] && echo 0 > $f
done < ${VARDIR}/proxyndp
rm -f ${VARDIR}/proxyndp
fi
EOF
push_indent;

View File

@ -593,8 +593,8 @@ conditionally_flush_conntrack() {
delete_proxyarp() {
if [ -f ${VARDIR}/proxyarp ]; then
while read address interface external haveroute; do
qt arp -i $external -d $address pub
[ -z "${haveroute}${g_noroutes}" ] && qt $IP -4 route del $address dev $interface
qt $IP -4 neigh del proxy $address dev $external
[ -z "${haveroute}${g_noroutes}" ] && qt $IP -4 route del $address/32 dev $interface
f=/proc/sys/net/ipv4/conf/$interface/proxy_arp
[ -f $f ] && echo 0 > $f
done < ${VARDIR}/proxyarp
@ -603,7 +603,7 @@ delete_proxyarp() {
fi
}
#
\#
# Remove all Shorewall-added rules
#
clear_firewall() {

View File

@ -573,6 +573,22 @@ conditionally_flush_conntrack() {
fi
}
#
# Clear Proxy NDP
#
delete_proxyndp() {
if [ -f ${VARDIR}/proxyndp ]; then
while read address interface external haveroute; do
qt $IP -6 neigh del proxy $address dev $external
[ -z "${haveroute}${g_noroutes}" ] && qt $IP -6 route del $address/128 dev $interface
f=/proc/sys/net/ipv6/conf/$interface/proxy_ndp
[ -f $f ] && echo 0 > $f
done < ${VARDIR}/proxyndp
rm -f ${VARDIR}/proxyndp
fi
}
#
# Remove all Shorewall-added rules
#