Commit b6ce3230 authored by Kirk Webb's avatar Kirk Webb

Squash commit containing fixes for ip alias support.

Reworked lookup/handling of linked interface objects for IP alias
vinterfaces.
parent da8d33b5
......@@ -126,6 +126,7 @@ sub doboot()
my $downcmds = "";
my @ifacelist = ();
my @ifacemap = ();
my %mac2iface = ();
print STDOUT "Checking Testbed interface configuration ... \n";
......@@ -198,8 +199,9 @@ sub doboot()
# Trivially parsable map for users, which associate an IP
# with a local interface.
push(@ifacemap, "$iface $inet $mac");
$mac2iface{$mac} = $iface;
}
elsif ($ifconfig->{ISVIRT} &&
elsif ($ifconfig->{ISVIRT} && $ifconfig->{ITYPE} ne 'alias' &&
(INXENVM() || SHADOW() ||
(GENVNODE() && GENVNODETYPE() eq 'openvz'))) {
......@@ -244,6 +246,7 @@ sub doboot()
# Trivially parsable map for users, which associate an IP
# with a local interface.
push(@ifacemap, "$iface $inet $mac");
$mac2iface{$mac} = $iface;
}
else {
my $itype = $ifconfig->{ITYPE};
......@@ -258,6 +261,22 @@ sub doboot()
my $encap = $ifconfig->{ENCAP};
my $vtag = $ifconfig->{VTAG};
# For IP aliases - late bind to the interface since it may
# have only just been created by a prior invocation of
# os_ifconfig_veth() (e.g., vlan interface). We keep a hash
# of mac->iface mappings, built up as we process ifconfig
# entries. Note that this implies that the prequisite
# interfaces have already been processed before aliases appear!
if ($itype eq "alias") {
if (exists($mac2iface{$vmac})) {
$iface = $mac2iface{$vmac};
} else {
warn("Could not find interface for IP alias: $vmac\n");
next;
}
$viface = "$iface:$id";
}
#
# A bit of history.
#
......@@ -295,6 +314,9 @@ sub doboot()
# Trivially parsable map for users, which associate an IP
# with a local interface.
push(@ifacemap, "$viface $inet $vmac");
if ($itype ne "alias") {
$mac2iface{$vmac} = $viface;
}
}
}
......
......@@ -83,7 +83,7 @@ use librc;
# IMPORTANT NOTE: if you change the version here, you must also change it
# in clientside/lib/tmcd/tmcd.h!
#
sub TMCD_VERSION() { 39; };
sub TMCD_VERSION() { 40; };
libtmcc::configtmcc("version", TMCD_VERSION());
# Control tmcc timeout.
......
......@@ -429,15 +429,6 @@ sub os_ifconfig_line($$$$$$$$;$$$)
return ($uplines, $downlines);
}
#
# Simple setup for IP aliases.
#
if ($iface_type eq "alias") {
$uplines = "$IPBIN addr add $inet/$mask dev $iface";
$downlines = "$IPBIN addr del $inet/$mask dev $iface";
return ($uplines, $downlines);
}
#
# Special handling for new style interfaces (which have settings).
# This should all move into per-type modules at some point.
......@@ -882,11 +873,8 @@ sub os_ifconfig_veth($$$$$;$$$$%)
# IP aliases
#
if ($itype eq "alias") {
my $aif = "$iface:$id";
$uplines = sprintf($IFCONFIG, $aif, $inet, $mask);
$downlines = "$IFCONFIGBIN $aif down";
$uplines = "$IPBIN addr add $inet/$mask dev $iface";
$downlines = "$IPBIN addr del $inet/$mask dev $iface";
return ($uplines, $downlines);
}
......
#
# IP alias support
#
use strict;
use libdb;
sub DoUpdate($$$)
{
my ($dbhandle, $dbname, $version) = @_;
if (!DBSlotExists("virt_lans", "ip_aliases")) {
DBQueryFatal("ALTER TABLE virt_lans ADD ".
" `ip_aliases` TINYTEXT ".
" AFTER implemented_by_link");
}
DBQueryFatal("REPLACE INTO table_regex VALUES ".
" ('virt_lans','ip_aliases','text','redirect', ".
" 'default:tinytext',0,0,NULL)");
return 0;
}
# Local Variables:
# mode:perl
# End:
......@@ -8988,39 +8988,40 @@ sub UpLoadIPAddresses($)
# and virtual nodes.
#
# Note well that the MAC addresses used for these IP alias
# entries purposely matches that of the interface on which
# it is to be setup on the client-side. This is how the
# client-side knows which interface to apply it to.
# entries purposely match those of the interfaces on which
# they are to be setup on the client-side. This is how the
# client-side knows which interface to apply them to.
#
if ($member->{ip_aliases}) {
my $pnodename = $self->solution_v2p()->{$vnodename};
my $pnode = $self->pnodes()->{$pnodename};
my $pifobj = Interface->LookupByIface($pnode, $iface);
if ($member->ip_aliases()) {
my %argref = (
mac => $pifobj->mac(),
mask => $mask,
type => "ipalias",
type => "alias",
iface => $iface,
exptidx => $self->experiment->idx(),
virtlanidx => $virtlan->idx(),
);
# Grab VM info, if this is a VM that is. The target inteface
# for tha alias should have already been created in the
# vinterfaces table.
my $pnodename = $self->solution_v2p()->{$vnodename};
# Grab VM info, if this is a VM that is.
if (exists($self->solution_v2v()->{$vnodename})) {
my $pvnodename = $self->solution_v2v()->{$vnodename};
my $pvnode = $self->pnodes()->{$pvnodename};
if ($pvnode->isjailed()) {
$argref{vnode_id} = $pvnodename;
my $vifobj = Interface::VInterface->LookupByVirtLan(
$self->experiment(), $virtlan->vname(), $vnodename);
$argref->{mac} = $vifobj->mac();
$argref{vnode_id} = $self->solution_v2v()->{$vnodename};
}
# Is the node connecting via virtual interface? The
# target inteface for tha alias should have already
# been created in the vinterfaces table by this time.
if ($member->usevirtiface()) {
my $vif = Interface::VInterface->LookupByVirtLan(
$self->experiment(), $virtlan->vname(), $vnodename);
$argref{mac} = $vif->mac();
} else {
my $pnode = $self->pnodes()->{$pnodename};
my $pif = Interface->LookupByIface($pnode, $iface);
$argref{mac} = $pif->mac();
}
my @ip_aliases = split(/,/, $member->{ip_aliases});
my @ip_aliases = split(/,/, $member->ip_aliases());
foreach my $ipa (@ip_aliases) {
$argref{IP} = $ipa;
my $aiface =
......@@ -9031,7 +9032,7 @@ sub UpLoadIPAddresses($)
$self->printdb("IP Alias: $member - " .
(exists($argref{vnode_id}) ?
$argref{vnode_id} : $pnodename) .
":$mac $ipa ($aiface)\n");
":$argref{mac} $ipa ($aiface)\n");
}
}
}
......
......@@ -623,6 +623,7 @@ LanLink instproc fill_ips {} {
$self instvar sim
$self instvar widearea
$self instvar netmask
$self instvar used_ips
set isremote 0
set netmaskint [inet_atohl $netmask]
......@@ -667,14 +668,14 @@ LanLink instproc fill_ips {} {
}
set ipint [inet_atohl $ip]
set subnet [inet_hltoa [expr $ipint & $netmaskint]]
set ips($ip) 1
set used_ips($ip) 1
$sim use_subnet $subnet $netmask
}
if {$ipaliases != {}} {
foreach $ipalias $ipaliases {
foreach ipalias $ipaliases {
set ipint [inet_atohl $ipalias]
set subnet [inet_hltoa [expr $ipint & $netmaskint]]
set ips($ipalias) 1
set used_ips($ipalias) 1
$sim use_subnet $subnet $netmask
}
}
......@@ -1365,6 +1366,12 @@ Lan instproc updatedb {DB} {
lappend fields "fixed_iface"
}
# IP aliases
set ipaliases [$node get_ipaliases_port $port]
if {[llength $ipaliases] > 0} {
lappend fields "ip_aliases"
}
set values [list $self $nodeportraw $netmask $delay($nodeport) $rdelay($nodeport) $bandwidth($nodeport) $rbandwidth($nodeport) $backfill($nodeport) $rbackfill($nodeport) $loss($nodeport) $rloss($nodeport) $cost($nodeport) $widearea $emulated $uselinkdelay $nobwshaping $encap $limit_ $maxthresh_ $thresh_ $q_weight_ $linterm_ ${queue-in-bytes_} $bytes_ $mean_pktsize_ $wait_ $setbit_ $droptail_ $red_ $gentle_ $trivial_ok $protocol $is_accesspoint $node $port $ip $mustdelay]
if { [info exists ebandwidth($nodeport)] } {
......@@ -1390,6 +1397,12 @@ Lan instproc updatedb {DB} {
lappend values $fixed_iface($nodeport)
}
# IP aliases
if {[llength $ipaliases] > 0} {
set ipaliasesraw [join $ipaliases ","]
lappend values $ipaliasesraw
}
# openflow
#
# table: virt_lans
......
......@@ -222,7 +222,6 @@ Node instproc updatedb {DB} {
$self instvar rpms
$self instvar startup
$self instvar iplist
$self instvar ipaliaslist
$self instvar tarfiles
$self instvar failureaction
$self instvar inner_elab_role
......@@ -486,6 +485,8 @@ Node instproc updatedb {DB} {
Node instproc add_lanlink {lanlink} {
$self instvar portlist
$self instvar iplist
$self instvar ipaliaslist
$self instvar wantipaliaslist
$self instvar simulated
# Check if we're making too many lanlinks to this node
......@@ -502,7 +503,7 @@ Node instproc add_lanlink {lanlink} {
lappend portlist $lanlink
lappend iplist ""
lappend ipaliaslist ""
lappend wantaliaslist ""
lappend wantipaliaslist ""
return [expr [llength $portlist] - 1]
}
......
......@@ -2393,6 +2393,15 @@ COMMAND_PROTOTYPE(doifconfig)
row = mysql_fetch_row(res);
nrows--;
/*
* If the interface type is 'alias', and this is not
* do not process here. Such IP alias entries will be
* handled below. Old (very old) IP alias processing
* occurs via "IPALIAS=" lines, generated above.
*/
if (strcmp(row[6], "alias") == 0)
continue;
/*
* When the proxy is asking for the container, we give it info
* for a plain interface, since that is all it sees.
......@@ -2583,43 +2592,44 @@ COMMAND_PROTOTYPE(doifconfig)
* interface. They should work on both physical and virtual nodes.
*/
if (vers >= 40) {
char *bufp = buf;
MYSQL_RES *res;
MYSQL_ROW row;
int nrows;
char *nodecol = "";
nodecol = (reqp->isvnode && reqp->asvnode)
? "vnode_id" : "node_id";
? "v.vnode_id" : "v.node_id";
res = mydb_query("select v.IP, v.mask, v.mac, vll.vname "
res = mydb_query("select v.IP, v.mask, v.unit, v.mac, "
" vll.vname "
"from vinterfaces as v "
"left join virt_lan_lans as vll "
"on v.virtlanidx = vll.idx "
"and v.exptidx = vll.exptidx "
"where type='alias' and %s='%s'",
4, nodecol, reqp->nodeid);
"where v.type='alias' and %s='%s'",
5, nodecol, reqp->nodeid);
if (res == NULL)
goto adone;
goto ipadone;
nrows = (int)mysql_num_rows(res);
while (nrows > 0) {
nrows--;
row = mysql_fetch_row(res);
if (!row || !row[0] || !row[1] || !row[2] || !row[3])
if (!row || !row[0] || !row[1] || !row[2] ||
!row[3] || !row[4])
continue;
bufp += OUTPUT(bufp, ebufp - bufp,
OUTPUT(buf, sizeof(buf),
"INTERFACE IFACETYPE=alias "
"INET=%s MASK=%s MAC=%s "
"SPEED= DUPLEX= IFACE= "
"RTABID= LAN=%s"
row[0], row[1], row[2], row[3]);
"INET=%s MASK=%s ID=%s VMAC=%s PMAC=none "
"RTABID= ENCAPSULATE=0 LAN=%s VTAG=\n",
row[0], CHECKMASK(row[1]), row[2], row[3],
row[4]);
client_writeback(sock, buf, strlen(buf), tcp);
if (verbose)
info("%s: IFCONFIG: %s", reqp->nodeid, buf);
}
mysql_free_result(res);
adone: ;
ipadone: ;
}
return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment