#!/usr/bin/perl
use strict;
use lib "/etc/kvm/api";
use KVMapi; 

$|=1;


sub stop_bridge
{
	my $bridge = shift;
	my $id = shift;
	my $vlan = shift;

	my $vifname = sprintf("vif_%s_%s", $id, $vlan);
	print("vifname: '$vifname'\n");
	
	my @lines = `/usr/sbin/brctl show | /bin/grep eth | /usr/bin/awk '{ print \$1 }'`;
	foreach my $bridge (@lines)
	{
		chomp($bridge);
		system("/usr/sbin/brctl delif $bridge $vifname 2>/dev/null");
	}

	system("/sbin/ifconfig $vifname down 2>/dev/null");
	system("/usr/sbin/tunctl -d $vifname 1>/dev/null 2>/dev/null");

	return 0;
}

sub stop_route
{
	my $ip = shift;
	my $bridge = shift;
	my $id = shift;
	my $vlan = shift;

	my $vifname = sprintf("vif_%s_%s", $id, $vlan);
	print("vifname: '$vifname'\n");

	my $rvalue = 0;
	do
	{
		$rvalue = system("/sbin/route del -host $ip 2>/dev/null");
	} while ($rvalue == 0);



	stop_bridge($bridge, $id, $vlan);
	return 0;
}

sub start_route
{
	my $ip = shift;
	my $bridge = shift;
	my $id = shift;
	my $vlan = shift;

	start_bridge($bridge, $id, $vlan);

	my $vifname = sprintf("vif_%s_%s", $id, $vlan);

	system("/sbin/route add -host $ip dev $bridge 2>/dev/null");

	my @files=`find /proc/sys/net/ipv4/ -name "send_redirects"`;
	foreach my $file (@files)
	{
		system("echo 0 > $file");
	}
	system("echo 1 > /proc/sys/net/ipv4/ip_forward");

	return 0;
}

sub start_bridge
{
	my $bridge = shift;
	my $id = shift;
	my $vlan = shift;

	my $vifname = sprintf("vif_%s_%s", $id, $vlan);

	system("/usr/sbin/tunctl -b -u root -t $vifname 1>/dev/null 2>/dev/null");
	system("/usr/sbin/brctl addif $bridge $vifname 2>/dev/null");
	system("/sbin/ifconfig $vifname up 0.0.0.0 promisc 2>/dev/null");
	return 0;
}

my $name = shift;
$name =~ s/^vif_//;

my ($id, $vlan) = split(/_/, $name);
$vlan = int($vlan);

print("id: '$id', vlan: '$vlan'\n");

my $kvm;
my %opts;

opendir(DIR, "/etc/kvm/");
my @files=readdir(DIR);
closedir(DIR);
my $found = 0;
foreach my $file (@files)
{
	chomp($file);
	next unless ($file =~ /\.kvm$/);
	$file =~ s/\.kvm$//;

	$kvm = KVMapi->new($file);
	%opts = $kvm->getOptions();
	if ($opts{"id"} eq $id)
	{
		$found = 1;
		last
	}
}
if ($found == 0)
{
	die("unable to detect vm");
}

my $id = $opts{"id"};
for (my $i = 0; $i < $opts{"nics"}; $i++)
{
	next unless ($vlan eq $i);

	my $key = sprintf("nic%s", $i);
	my $mode = $opts{$key . "_mode"};
	my $bridge = $opts{$key . "_bridge"};
	my $ip = $opts{$key . "_ip"};

	printf("mode '$mode'");
	if ($mode eq 'route')
	{
		printf(" ip: '$ip', bridge: '$bridge'\n");
		printf("- clearing network...\n");
		stop_route($ip, $bridge, $id, $vlan);

		if ($0 =~ /ifup$/)
		{
			printf("- starting network...\n");
			start_route($ip, $bridge, $id, $vlan);
		}
	}
	else 	# bridge
	{
		printf(" bridge: '$bridge'\n");
		stop_bridge($bridge, $id, $vlan);
		if ($0 =~ /ifup$/)
		{
			printf("- starting network...\n");
			start_bridge($bridge, $id, $vlan);
		}
	}
}

exit(0);
