Commit b9252636 authored by Leigh Stoller's avatar Leigh Stoller

Change to how links involving shared nodes are done; whenever a shared

nodes is selected, those links must use vlan encap. Since shared node
selection is not done until late, we end up goaing back and modifying
the encap type and forcing a vlan to be created.

This is done cause the shared nodes (openvz) do not support veth
encap, and so arp causes leakage between experiments on the same node
that have common IP addresses.
parent 1f5cc798
......@@ -247,9 +247,11 @@ sub Create($$$)
my $self = {};
bless($self, $class);
$self->{'VIRTNODE'} = $virt_node;
$self->{'VTOP'} = $vtop;
$self->{'HASH'} = {};
$self->{'VIRTNODE'} = $virt_node;
$self->{'VTOP'} = $vtop;
$self->{'HASH'} = {};
# The virtlans this virtnode is a member of.
$self->{'MEMBERSHIP'} = {};
return $self;
}
......@@ -257,6 +259,8 @@ sub Create($$$)
sub virt_node($) { return $_[0]->{'VIRTNODE'}; }
sub vtop($) { return $_[0]->{'VTOP'}; }
sub hash($) { return $_[0]->{'HASH'}; }
sub membership($) { return $_[0]->{'MEMBERSHIP'}; }
sub memberlist($) { return values(%{ $_[0]->{'MEMBERSHIP'} }); }
# Break circular reference someplace to avoid exit errors.
sub DESTROY {
......@@ -265,6 +269,7 @@ sub DESTROY {
$self->{'VIRTNODE'} = undef;
$self->{'VTOP'} = undef;
$self->{'HASH'} = undef;
$self->{'MEMBERSHIP'} = undef;
}
sub Stringify($)
......@@ -1036,6 +1041,9 @@ sub LoadVirtLans($)
# Global map from vnode:port back to the lan object
$self->memberof()->{$vlanmember->member()} = $virtlan;
# Each virt_node has a list of all virt_lans it belongs to.
$vlanmember->virt_node()->membership()->{"$virtlan"} = $virtlan;
# Other fields we need below
my $delay = $vlanmember->delay();
my $bandwidth = $vlanmember->bandwidth();
......@@ -1894,46 +1902,25 @@ sub GenVirtLans($)
$trivial_ok = $vlan->_trivial_ok();
if ($sharednodes) {
my $newencap;
if ($sharednodes != $allnodes || $vlan->_needvlan()) {
#
# Change the encap type to vlan since that is supported.
#
if ($nodesdo{"vlan"} == $allnodes) {
$newencap = "vlan";
}
# Force this on.
$emulated = 1;
}
else {
if ($nodesdo{"veth-en"} == $allnodes) {
# Veth means encapsulated.
$newencap = "veth";
}
elsif ($nodesdo{"veth-ne"} == $allnodes) {
$newencap = "veth-ne";
}
elsif ($nodesdo{"vlan"} == $allnodes) {
$newencap = "vlan";
}
# Force this on.
$emulated = 1;
}
if (defined($newencap)) {
$encapval = $newencap;
$vlan->_emulated($emulated);
$vlan->_encapstyle($newencap);
$self->printdb("Converting encapstyle to ".
"$encapval on $vname\n");
}
else {
tberror("Cannot find a common encapstyle for $vname\n");
#
# All nodes must support vlan encapsulation since that is how we
# create the links. Even if only one node in the link or
# lan is on a shared node, they must all do vlan encap.
# If none of the nodes land on a shared node, then use the
# requested vlan encap. Right, this decision is actually made
# later after assign maps the resources.
#
if ($nodesdo{"vlan"} != $allnodes) {
tberror("Shared nodes requested for $vname, but vlan encapsulation\n".
"not supported on all nodes.\n");
$errors++;
}
}
elsif ($nodesdo{$encapval} == $allnodes) {
#
# Regardless of shared nodes, there must be a common encapsulation style
# in case no shared nodes are used (and vlan encap is not needed).
#
if ($nodesdo{$encapval} == $allnodes) {
#
# All members support the encapsulation style, use it.
#
......@@ -3189,7 +3176,7 @@ sub AddLinkToSolution($$$$$$$$)
tberror("Bad vlink in solution: $vlink\n");
return -1;
}
$self->solution_plinks()->{$vlink} =
[$linktag,$virtlan,$trivial,$direct,$member0,$member1];
if (!$trivial) {
......@@ -3927,6 +3914,18 @@ sub AllocNodes($)
$self->pnodes()->{$vpnode->node_id()} = $vpnode;
$virtnode->_onsharednode($pnode->_sharedhost());
$virtnode->_pnode($vpnode);
#
# Minor post processing; Whenever a shared node is
# selected by assign, must reset the encap style of
# the lans it is a memberof, to vlan encap.
#
if ($virtnode->_onsharednode()) {
foreach my $virtlan ($virtnode->memberlist()) {
$virtlan->_needvlan(1);
$virtlan->_encapstyle("vlan");
}
}
}
else {
# Default this for physnodes.
......@@ -4480,14 +4479,9 @@ sub InterpLinks($)
# there is a postpass to merge the vlans into a single
# supervlan since a nodeport can be in just a single vlan.
#
# If both nodes shared, do not need the vlan.
# If only one of the nodes is shared, must still create
# an underlying vlan.
#
#
if ((!($virtnodeA->_onsharednode() &&
$virtnodeB->_onsharednode())) ||
$virtlan->_needvlan()) {
if ($virtnodeA->_onsharednode() ||
$virtnodeB->_onsharednode() || $virtlan->_needvlan()) {
my $lanid = "v" . "$lan" . $vlanid++;
$protovlan = ProtoLan->Create($experiment, $lanid,
......@@ -4597,7 +4591,7 @@ sub InterpLinks($)
"$nodeA:$portA,$nodeB:$portB\n");
$protolink = ProtoLan->Create($experiment, $lan,
$self->impotent(),
$self->impotent() ||
$self->alloconly());
$protolink->SetType("trivial");
$protolink->SetRole("link/lan");
......@@ -4655,9 +4649,7 @@ sub InterpLinks($)
#
my $protovlan;
if (!$virtlan->_sharednodes() ||
$virtlan->_sharednodes() != $virtlan->memberlist() ||
$virtlan->_needvlan()) {
if (!$virtlan->_sharednodes() || $virtlan->_needvlan()) {
if (exists($protovlans{$lan})) {
$protovlan = $protovlans{$lan};
}
......@@ -5432,7 +5424,7 @@ sub NewVirtIface($$$$;$)
my $ip = $member->ip();
my $mask = $member->mask();
my $encap = $virtlan->_encapstyle();
my $isveth = ($encap eq "veth" || $encap eq "veth-ne");
my $isveth = (($encap eq "veth" || $encap eq "veth-ne") ? 1 : 0);
my $vllidx = $virtlan->idx();
my $rtabid = $self->getrtabid($pnode, $member);
my $exptidx = $self->experiment()->idx();
......
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