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() ...@@ -126,6 +126,7 @@ sub doboot()
my $downcmds = ""; my $downcmds = "";
my @ifacelist = (); my @ifacelist = ();
my @ifacemap = (); my @ifacemap = ();
my %mac2iface = ();
print STDOUT "Checking Testbed interface configuration ... \n"; print STDOUT "Checking Testbed interface configuration ... \n";
...@@ -198,8 +199,9 @@ sub doboot() ...@@ -198,8 +199,9 @@ sub doboot()
# Trivially parsable map for users, which associate an IP # Trivially parsable map for users, which associate an IP
# with a local interface. # with a local interface.
push(@ifacemap, "$iface $inet $mac"); push(@ifacemap, "$iface $inet $mac");
$mac2iface{$mac} = $iface;
} }
elsif ($ifconfig->{ISVIRT} && elsif ($ifconfig->{ISVIRT} && $ifconfig->{ITYPE} ne 'alias' &&
(INXENVM() || SHADOW() || (INXENVM() || SHADOW() ||
(GENVNODE() && GENVNODETYPE() eq 'openvz'))) { (GENVNODE() && GENVNODETYPE() eq 'openvz'))) {
...@@ -244,6 +246,7 @@ sub doboot() ...@@ -244,6 +246,7 @@ sub doboot()
# Trivially parsable map for users, which associate an IP # Trivially parsable map for users, which associate an IP
# with a local interface. # with a local interface.
push(@ifacemap, "$iface $inet $mac"); push(@ifacemap, "$iface $inet $mac");
$mac2iface{$mac} = $iface;
} }
else { else {
my $itype = $ifconfig->{ITYPE}; my $itype = $ifconfig->{ITYPE};
...@@ -258,6 +261,22 @@ sub doboot() ...@@ -258,6 +261,22 @@ sub doboot()
my $encap = $ifconfig->{ENCAP}; my $encap = $ifconfig->{ENCAP};
my $vtag = $ifconfig->{VTAG}; 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. # A bit of history.
# #
...@@ -295,6 +314,9 @@ sub doboot() ...@@ -295,6 +314,9 @@ sub doboot()
# Trivially parsable map for users, which associate an IP # Trivially parsable map for users, which associate an IP
# with a local interface. # with a local interface.
push(@ifacemap, "$viface $inet $vmac"); push(@ifacemap, "$viface $inet $vmac");
if ($itype ne "alias") {
$mac2iface{$vmac} = $viface;
}
} }
} }
......
...@@ -83,7 +83,7 @@ use librc; ...@@ -83,7 +83,7 @@ use librc;
# IMPORTANT NOTE: if you change the version here, you must also change it # IMPORTANT NOTE: if you change the version here, you must also change it
# in clientside/lib/tmcd/tmcd.h! # in clientside/lib/tmcd/tmcd.h!
# #
sub TMCD_VERSION() { 39; }; sub TMCD_VERSION() { 40; };
libtmcc::configtmcc("version", TMCD_VERSION()); libtmcc::configtmcc("version", TMCD_VERSION());
# Control tmcc timeout. # Control tmcc timeout.
......
...@@ -429,15 +429,6 @@ sub os_ifconfig_line($$$$$$$$;$$$) ...@@ -429,15 +429,6 @@ sub os_ifconfig_line($$$$$$$$;$$$)
return ($uplines, $downlines); 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). # Special handling for new style interfaces (which have settings).
# This should all move into per-type modules at some point. # This should all move into per-type modules at some point.
...@@ -882,11 +873,8 @@ sub os_ifconfig_veth($$$$$;$$$$%) ...@@ -882,11 +873,8 @@ sub os_ifconfig_veth($$$$$;$$$$%)
# IP aliases # IP aliases
# #
if ($itype eq "alias") { if ($itype eq "alias") {
my $aif = "$iface:$id"; $uplines = "$IPBIN addr add $inet/$mask dev $iface";
$downlines = "$IPBIN addr del $inet/$mask dev $iface";
$uplines = sprintf($IFCONFIG, $aif, $inet, $mask);
$downlines = "$IFCONFIGBIN $aif down";
return ($uplines, $downlines); 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($) ...@@ -8988,39 +8988,40 @@ sub UpLoadIPAddresses($)
# and virtual nodes. # and virtual nodes.
# #
# Note well that the MAC addresses used for these IP alias # Note well that the MAC addresses used for these IP alias
# entries purposely matches that of the interface on which # entries purposely match those of the interfaces on which
# it is to be setup on the client-side. This is how the # they are to be setup on the client-side. This is how the
# client-side knows which interface to apply it to. # client-side knows which interface to apply them to.
# #
if ($member->{ip_aliases}) { if ($member->ip_aliases()) {
my $pnodename = $self->solution_v2p()->{$vnodename};
my $pnode = $self->pnodes()->{$pnodename};
my $pifobj = Interface->LookupByIface($pnode, $iface);
my %argref = ( my %argref = (
mac => $pifobj->mac(),
mask => $mask, mask => $mask,
type => "ipalias", type => "alias",
iface => $iface, iface => $iface,
exptidx => $self->experiment->idx(), exptidx => $self->experiment->idx(),
virtlanidx => $virtlan->idx(), virtlanidx => $virtlan->idx(),
); );
# Grab VM info, if this is a VM that is. The target inteface my $pnodename = $self->solution_v2p()->{$vnodename};
# for tha alias should have already been created in the
# vinterfaces table. # Grab VM info, if this is a VM that is.
if (exists($self->solution_v2v()->{$vnodename})) { if (exists($self->solution_v2v()->{$vnodename})) {
my $pvnodename = $self->solution_v2v()->{$vnodename}; $argref{vnode_id} = $self->solution_v2v()->{$vnodename};
my $pvnode = $self->pnodes()->{$pvnodename}; }
if ($pvnode->isjailed()) {
$argref{vnode_id} = $pvnodename; # Is the node connecting via virtual interface? The
my $vifobj = Interface::VInterface->LookupByVirtLan( # target inteface for tha alias should have already
$self->experiment(), $virtlan->vname(), $vnodename); # been created in the vinterfaces table by this time.
$argref->{mac} = $vifobj->mac(); 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) { foreach my $ipa (@ip_aliases) {
$argref{IP} = $ipa; $argref{IP} = $ipa;
my $aiface = my $aiface =
...@@ -9031,7 +9032,7 @@ sub UpLoadIPAddresses($) ...@@ -9031,7 +9032,7 @@ sub UpLoadIPAddresses($)
$self->printdb("IP Alias: $member - " . $self->printdb("IP Alias: $member - " .
(exists($argref{vnode_id}) ? (exists($argref{vnode_id}) ?
$argref{vnode_id} : $pnodename) . $argref{vnode_id} : $pnodename) .
":$mac $ipa ($aiface)\n"); ":$argref{mac} $ipa ($aiface)\n");
} }
} }
} }
......
...@@ -623,6 +623,7 @@ LanLink instproc fill_ips {} { ...@@ -623,6 +623,7 @@ LanLink instproc fill_ips {} {
$self instvar sim $self instvar sim
$self instvar widearea $self instvar widearea
$self instvar netmask $self instvar netmask
$self instvar used_ips
set isremote 0 set isremote 0
set netmaskint [inet_atohl $netmask] set netmaskint [inet_atohl $netmask]
...@@ -667,14 +668,14 @@ LanLink instproc fill_ips {} { ...@@ -667,14 +668,14 @@ LanLink instproc fill_ips {} {
} }
set ipint [inet_atohl $ip] set ipint [inet_atohl $ip]
set subnet [inet_hltoa [expr $ipint & $netmaskint]] set subnet [inet_hltoa [expr $ipint & $netmaskint]]
set ips($ip) 1 set used_ips($ip) 1
$sim use_subnet $subnet $netmask $sim use_subnet $subnet $netmask
} }
if {$ipaliases != {}} { if {$ipaliases != {}} {
foreach $ipalias $ipaliases { foreach ipalias $ipaliases {
set ipint [inet_atohl $ipalias] set ipint [inet_atohl $ipalias]
set subnet [inet_hltoa [expr $ipint & $netmaskint]] set subnet [inet_hltoa [expr $ipint & $netmaskint]]
set ips($ipalias) 1 set used_ips($ipalias) 1
$sim use_subnet $subnet $netmask $sim use_subnet $subnet $netmask
} }
} }
...@@ -1365,6 +1366,12 @@ Lan instproc updatedb {DB} { ...@@ -1365,6 +1366,12 @@ Lan instproc updatedb {DB} {
lappend fields "fixed_iface" 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] 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)] } { if { [info exists ebandwidth($nodeport)] } {
...@@ -1390,6 +1397,12 @@ Lan instproc updatedb {DB} { ...@@ -1390,6 +1397,12 @@ Lan instproc updatedb {DB} {
lappend values $fixed_iface($nodeport) lappend values $fixed_iface($nodeport)
} }
# IP aliases
if {[llength $ipaliases] > 0} {
set ipaliasesraw [join $ipaliases ","]
lappend values $ipaliasesraw
}
# openflow # openflow
# #
# table: virt_lans # table: virt_lans
......
...@@ -222,7 +222,6 @@ Node instproc updatedb {DB} { ...@@ -222,7 +222,6 @@ Node instproc updatedb {DB} {
$self instvar rpms $self instvar rpms
$self instvar startup $self instvar startup
$self instvar iplist $self instvar iplist
$self instvar ipaliaslist
$self instvar tarfiles $self instvar tarfiles
$self instvar failureaction $self instvar failureaction
$self instvar inner_elab_role $self instvar inner_elab_role
...@@ -486,6 +485,8 @@ Node instproc updatedb {DB} { ...@@ -486,6 +485,8 @@ Node instproc updatedb {DB} {
Node instproc add_lanlink {lanlink} { Node instproc add_lanlink {lanlink} {
$self instvar portlist $self instvar portlist
$self instvar iplist $self instvar iplist
$self instvar ipaliaslist
$self instvar wantipaliaslist
$self instvar simulated $self instvar simulated
# Check if we're making too many lanlinks to this node # Check if we're making too many lanlinks to this node
...@@ -502,7 +503,7 @@ Node instproc add_lanlink {lanlink} { ...@@ -502,7 +503,7 @@ Node instproc add_lanlink {lanlink} {
lappend portlist $lanlink lappend portlist $lanlink
lappend iplist "" lappend iplist ""
lappend ipaliaslist "" lappend ipaliaslist ""
lappend wantaliaslist "" lappend wantipaliaslist ""
return [expr [llength $portlist] - 1] return [expr [llength $portlist] - 1]
} }
......
...@@ -2393,6 +2393,15 @@ COMMAND_PROTOTYPE(doifconfig) ...@@ -2393,6 +2393,15 @@ COMMAND_PROTOTYPE(doifconfig)
row = mysql_fetch_row(res); row = mysql_fetch_row(res);
nrows--; 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 * When the proxy is asking for the container, we give it info
* for a plain interface, since that is all it sees. * for a plain interface, since that is all it sees.
...@@ -2583,43 +2592,44 @@ COMMAND_PROTOTYPE(doifconfig) ...@@ -2583,43 +2592,44 @@ COMMAND_PROTOTYPE(doifconfig)
* interface. They should work on both physical and virtual nodes. * interface. They should work on both physical and virtual nodes.
*/ */
if (vers >= 40) { if (vers >= 40) {
char *bufp = buf;
MYSQL_RES *res; MYSQL_RES *res;
MYSQL_ROW row; MYSQL_ROW row;
int nrows; int nrows;
char *nodecol = ""; char *nodecol = "";
nodecol = (reqp->isvnode && reqp->asvnode) 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 " "from vinterfaces as v "
"left join virt_lan_lans as vll " "left join virt_lan_lans as vll "
"on v.virtlanidx = vll.idx " "on v.virtlanidx = vll.idx "
"and v.exptidx = vll.exptidx " "and v.exptidx = vll.exptidx "
"where type='alias' and %s='%s'", "where v.type='alias' and %s='%s'",
4, nodecol, reqp->nodeid); 5, nodecol, reqp->nodeid);
if (res == NULL) if (res == NULL)
goto adone; goto ipadone;
nrows = (int)mysql_num_rows(res); nrows = (int)mysql_num_rows(res);
while (nrows > 0) { while (nrows > 0) {
nrows--; nrows--;
row = mysql_fetch_row(res); 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; continue;
bufp += OUTPUT(bufp, ebufp - bufp, OUTPUT(buf, sizeof(buf),
"INTERFACE IFACETYPE=alias " "INTERFACE IFACETYPE=alias "
"INET=%s MASK=%s MAC=%s " "INET=%s MASK=%s ID=%s VMAC=%s PMAC=none "
"SPEED= DUPLEX= IFACE= " "RTABID= ENCAPSULATE=0 LAN=%s VTAG=\n",
"RTABID= LAN=%s" row[0], CHECKMASK(row[1]), row[2], row[3],
row[0], row[1], row[2], row[3]); row[4]);
client_writeback(sock, buf, strlen(buf), tcp); client_writeback(sock, buf, strlen(buf), tcp);
if (verbose) if (verbose)
info("%s: IFCONFIG: %s", reqp->nodeid, buf); info("%s: IFCONFIG: %s", reqp->nodeid, buf);
} }
mysql_free_result(res); mysql_free_result(res);
adone: ; ipadone: ;
} }
return 0; 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