Commit 81a5b97f authored by Jonathon Duerig's avatar Jonathon Duerig
Browse files

Merge branch 'master' of git-public.flux.utah.edu:/flux/git/emulab-devel

parents bc2426dd 157d3802
......@@ -177,7 +177,7 @@ my ($dev,$ino,$mode,$nlink,undef,undef,$rdev,$size,
my $if_mod_since = 0;
$if_mod_since = str2time($ENV{HTTP_IF_MODIFIED_SINCE})
if defined $ENV{HTTP_IF_MODIFIED_SINCE};
if ($if_mod_since > 0 && $if_mod_since <= $mtime) {
if ($mtime <= $if_mod_since) {
print "Status: 304 Not Modified\n\n";
} else {
print "Content-Type: $mime_type\n" if defined $mime_type;
......
......@@ -2735,6 +2735,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
dhcpd/dhcpd.conf.template dhcpd/GNUmakefile \
dhcpd/dhcpd.conf.subboss.template \
install/GNUmakefile \
install/libinstall.pm install/update-install install/update-testbed \
install/ops-install install/boss-install install/fs-install \
install/load-descriptors install/dump-descriptors \
install/newnode_sshkeys/GNUmakefile install/smb.conf.head \
......
......@@ -984,6 +984,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
install/load-descriptors install/dump-descriptors \
install/newnode_sshkeys/GNUmakefile install/smb.conf.head \
install/clrhouse-install \
install/libinstall.pm install/update-install install/update-testbed \
mote/GNUmakefile mote/tbuisp mote/tbsgmotepower mote/newmote \
mote/sgtools/GNUmakefile \
robots/GNUmakefile robots/tbsetdest/GNUmakefile \
......
......@@ -99,6 +99,7 @@ my $EXPT_RESOURCESHOSED = 0;
"virt_simnode_attributes",
"virt_user_environment",
"virt_parameters",
"virt_paths",
# vis_nodes is locked during update in prerender, so we
# will get a consistent dataset when we backup.
"vis_nodes",
......
......@@ -72,6 +72,7 @@ my $debug = 0;
"elabinelab_attributes" => [ "role", "attrkey", "ordering" ],
"virt_tiptunnels" => [ "host", "vnode" ],
"virt_parameters" => [ "name", "value" ],
"virt_paths" => [ "pathname", "segmentname"],
);
#
......@@ -1184,5 +1185,10 @@ use vars qw(@ISA);
@ISA = "VirtExperiment::VirtTableRow";
use VirtExperiment;
package VirtExperiment::VirtTableRow::virt_paths;
use vars qw(@ISA);
@ISA = "VirtExperiment::VirtTableRow";
use VirtExperiment;
# _Always_ make sure that this 1 is at the end of the file...
1;
......@@ -802,6 +802,10 @@ sub StartSlivers($$$$)
}
$count++;
}
# Everything failed, stop now.
return -1
if (!@tmp);
MapNodes($experiment, $verbose);
return WaitForSlivers($experiment, $user, $verbose, @tmp);
......
......@@ -116,9 +116,12 @@ my %virtual_tables =
"virt_tiptunnels" => { rows => undef,
tag => "tiptunnels",
row => "tiptunnel"},
"virt_parameters" => { rows => undef,
tag => "parameters",
row => "parameter"},
"virt_parameters" => { rows => undef,
tag => "parameters",
row => "parameter"},
"virt_paths" => { rows => undef,
tag => "path_members",
row => "path_member"},
# This is a fake table. See below. If we add more, lets generalize.
"external_sourcefiles" => { rows => undef,
tag => "nsfiles",
......
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2003 University of Utah and the Flux Group.
# Copyright (c) 2000-2010 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -9,11 +9,22 @@
#include <event.h>
event_handle_t event_register(char *name, int threaded);
event_handle_t event_register_withkeyfile(char *name, int threaded, char *keyfile);
event_handle_t event_register_withkeydata(char *name, int threaded, unsigned char *keydata, int len);
event_handle_t event_register_withkeyfile_withretry(char *name, int threaded, char *keyfile, int retrycount);
event_handle_t event_register_withkeydata_withretry(char *name, int threaded, unsigned char *keydata, int len, int retrycount);
Register with the testbed event system. NAME specifies the name of
the event server. Returns a pointer to a handle that may be passed
to other event system routines if the operation is successful, NULL
otherwise.
Register with the testbed event system with an optional HMAC key.
In all forms, NAME specifies the name of the event server and THREADED is
an indication as to whether the calling application is multi-threaded.
Returns a pointer to a handle that may be passed to other event system
routines if the operation is successful, NULL otherwise.
The syntax of the NAME parameter is inherited from elvin, and is a subset
of their URI syntax. It is of the form elvin://<server>:<port> where
<server> is the IP or DNS name of the server, and PORT is the TCP port
number to use.
The THREADED parameter should be set to 1 if the registering
client is multi-threaded. If THREADED is 1, the event
......@@ -24,16 +35,16 @@
event loop, and the client must call event_main after connecting in
order to receive notifications.
Elvin note: NAME is a URL of the form "elvin:/[protocol
stack]/[endpoint]", where a protocol stack names a transport
module, a security module, and a marshaling module as a comma
separated list (e.g., "http,none,xml"), and the endpoint format
is dependent on the transport module used. If no protocol
stack is given, the default stack (tcp, none, xdr) is used. For the
testbed's purposes, "elvin://HOSTNAME" should suffice. If NAME
is NULL, then Elvin's server discovery protocol will be used to find
the Elvin server.
In the _withretry forms, RETRYCOUNT is the number of attempt to try
making a connection to the server before failing. Retries happen
at a transport-specific interval, in the case of pubsub (the current
and only supported transport) it is 5 seconds.
In the _withkey* forms, the given KEYDATA and LEN or the contents of
KEYFILE are used as a key for the keyed-hash MAC computation to
authenticate all events sent or received via the returned handle.
The HMAC is a SHA1 hash computed using the OpenSSL HMAC_* routines.
Event HMACs appear as opaque attributes in events.
* event_unregister: Unregister with the testbed event system
......@@ -52,9 +63,20 @@
int event_main(event_handle_t handle);
Enter the main loop of the event system, waiting to receive event
notifications. Returns non-zero if the operation is successful, 0
otherwise.
notifications. Remains in the main loop until an error occurs or
event_stop_main is called. Returns non-zero if the operation is
successful, 0 otherwise. Should only be called by single-threaded
programs.
* event_stop_main: Force event_main to return
#include <event.h>
event_stop_main(event_handle_t handle)
Can be called from an event handler or signal handler to force the
main loop to return, either to check for a completion condition or
to handle other, non event related processing.
* event_notify: Send an event notification
......@@ -67,6 +89,8 @@
allocated by event_notification_alloc, and may optionally
have attributes added to it by event_notification_put_*.
Returns non-zero if the operation is successful, 0 otherwise.
If HANDLE has an associated hash key, an HMAC is computed and
added as an attribute before sending.
Note that NOTIFICATION is not deallocated by event_notify. The
caller is responsible for deallocating the notification when it
......@@ -81,15 +105,23 @@
event_notification_t notification,
struct timeval *time);
Schedule the event notification NOTIFICATION to be sent at time
TIME. NOTIFICATION is allocated by event_notification_alloc,
Send the indicated notification as a "scheduled" event.
NOTIFICATION is allocated by event_notification_alloc,
and may optionally have attributes added to it by
event_notification_put_*. Returns non-zero if the operation
is successful, 0 otherwise.
This function essentially operates as a deferred event_notify.
event_notify sends notifications immediately,
whereas event_schedule sends notifications at some later time.
event_notify sends notifications immediately to recipients,
whereas event_schedule causes notifications to be sent at
some later time.
IMPORTANT NOTE: scheduled events are NOT held in the calling process
for later delivery. Instead, event_schedule adds a SCHEDULER=1 attribute
to the notification along with attributes for the delivery time, and
then uses event_notify to immediately send the event. There must be
an event agent subscribed to SCHEDULER events that implements the
queuing and later sending of the unadorned notification.
Note that NOTIFICATION is not deallocated by event_schedule.
The caller is responsible for deallocating the notification
......
......@@ -807,7 +807,7 @@ Phase "syslog", "Setting up syslog", sub {
"$LOGDIR/stated.log 640 9 1000 * Z ".
"/var/run/stated.pid 31",
"$LOGDIR/checknodes.log 640 14 300 * Z ".
"/var/run/checknodes.pid",
"/var/run/checknodes_daemon.pid",
"$LOGDIR/osselect.log 640 9 300 * Z",
"$LOGDIR/power.log 640 7 300 * Z",
"$LOGDIR/frisbeed.log 640 7 300 * Z",
......@@ -824,7 +824,17 @@ Phase "syslog", "Setting up syslog", sub {
"$LOGDIR/plablinkdata.log 640 7 1000 * Z",
"$LOGDIR/xmlrpcbag.log 640 7 300 * Z",
"$LOGDIR/sshxmlrpc.log 640 7 300 * Z",
"$LOGDIR/sslxmlrpc.log 640 7 300 * Z");
"$LOGDIR/sslxmlrpc.log 640 7 300 * Z",
"$LOGDIR/reloadlog 640 9 1000 * Z ".
"/var/run/reload_daemon.pid",
"$LOGDIR/checkuplog 640 9 1000 * Z ".
"/var/run/checkup_daemon.pid",
"$LOGDIR/poollog 640 9 1000 * Z ".
"/var/run/pool_daemon.pid",
"$LOGDIR/expire_daemon.log 640 9 1000 * Z ".
"/var/run/expire_daemon.pid",
"$LOGDIR/sa_daemon.log 640 9 1000 * Z ".
"/var/run/sa_daemon.pid");
};
};
......
......@@ -64,12 +64,18 @@ $| = 1;
BEGIN
{
if (-e "../Makeconf") {
my $srcdir = "@top_srcdir@";
my $objdir = `/bin/pwd`;
chomp($objdir);
# Prior to first install or running from object dir.
unshift(@INC, "$objdir/../db");
unshift(@INC, "$objdir/@top_srcdir@/install");
unshift(@INC, "$objdir/@top_srcdir@/tbsetup");
if ($srcdir =~ /^\//) {
unshift(@INC, "$srcdir/install");
unshift(@INC, "$srcdir/tbsetup");
} else {
unshift(@INC, "$objdir/$srcdir/install");
unshift(@INC, "$objdir/$srcdir/tbsetup");
}
unshift(@INC, "$objdir/../tbsetup");
}
}
......@@ -117,10 +123,17 @@ if (! (-e "../db/dbupdate" && -e "./update-install")) {
my $objdir = `/bin/pwd`;
chomp($objdir);
my $abssrcdir;
if ($SRCDIR =~ /^\//) {
$abssrcdir = "$SRCDIR";
} else {
$abssrcdir = "$objdir/$SRCDIR";
}
my @INCDIRS = ("-I${objdir}", "-I${objdir}/../tbsetup",
"-I${objdir}/../db",
"-I${objdir}/${SRCDIR}/tbsetup",
"-I${objdir}/${SRCDIR}/install",
"-I${abssrcdir}/tbsetup",
"-I${abssrcdir}/install",
# To catch a few extra things that do not normally change.
"-I@prefix@/lib"
);
......
#!/usr/bin/perl -wT
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2009 University of Utah and the Flux Group.
# Copyright (c) 2008-2010 University of Utah and the Flux Group.
# All rights reserved.
#
package GeniCertificate;
......@@ -587,6 +587,21 @@ sub StoreCRL($$$)
return 0;
}
#
# Remove a CRL.
#
sub DeleteCRL($$)
{
my ($class, $authority) = @_;
my $uuid = $authority->uuid();
DBQueryWarn("delete from geni_crls where uuid='$uuid'")
or return -1;
return 0;
}
############################################################################
#
# Wrapper for local users.
......
......@@ -77,6 +77,7 @@ $| = 1;
use lib "@prefix@/lib";
use libtestbed;
use libdb qw(TBSetSiteVar TBOPSPID DBQueryFatal);
use emutil qw(TBGetUniqueIndex);
use User;
use Project;
use Experiment;
......
#!/usr/bin/perl -w
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2009 University of Utah and the Flux Group.
# Copyright (c) 2008-2010 University of Utah and the Flux Group.
# All rights reserved.
#
use strict;
......@@ -66,6 +66,7 @@ elsif ($authority->type() eq "sa") {
if (GeniUser->DeleteAll($authority) != 0) {
fatal("Could not delete users for $authority");
}
GeniCertificate->DeleteCRL($authority);
}
elsif ($authority->type() eq "ses") {
# Nothing to do.
......@@ -73,6 +74,7 @@ elsif ($authority->type() eq "ses") {
else {
fatal("Do not know how to delete $authority");
}
if ($authority->Delete() != 0) {
fatal("Could not delete components for $authority");
}
......
......@@ -3829,6 +3829,8 @@ CREATE TABLE `virt_lans` (
`trace_db` tinyint(1) NOT NULL default '0',
`fixed_iface` varchar(128) default '',
`layer` tinyint(4) NOT NULL default '2',
`implemented_by_path` tinytext,
`implemented_by_link` tinytext,
PRIMARY KEY (`exptidx`,`vname`,`vnode`,`vport`),
UNIQUE KEY `vport` (`pid`,`eid`,`vname`,`vnode`,`vport`),
KEY `pid` (`pid`,`eid`,`vname`),
......@@ -3932,6 +3934,25 @@ CREATE TABLE `virt_parameters` (
UNIQUE KEY `pideid` (`pid`,`eid`,`name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `virt_paths`
--
DROP TABLE IF EXISTS `virt_paths`;
CREATE TABLE `virt_paths` (
`pid` varchar(12) NOT NULL default '',
`eid` varchar(32) NOT NULL default '',
`exptidx` int(11) NOT NULL default '0',
`pathname` varchar(32) NOT NULL default '',
`segmentname` varchar(32) NOT NULL default '',
`segmentindex` tinyint(4) unsigned NOT NULL default '0',
`layer` tinyint(4) NOT NULL default '0',
PRIMARY KEY (`exptidx`,`pathname`,`segmentname`),
UNIQUE KEY `segidx` (`exptidx`,`pathname`,`segmentindex`),
KEY `pid` (`pid`,`eid`,`pathname`),
KEY `pideid` (`pid`,`eid`,`pathname`,`segmentname`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `virt_programs`
--
......
......@@ -691,7 +691,7 @@ REPLACE INTO table_regex VALUES ('virt_node_desires','desire','text','regex','^[
REPLACE INTO table_regex VALUES ('virt_node_desires','weight','int','redirect','default:float',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_nodes','pid','text','redirect','projects:pid',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_nodes','eid','text','redirect','experiments:eid',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_nodes','ips','text','regex','^(\\d{1,2}:\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3} {0,1})*$',0,1024,NULL);
REPLACE INTO table_regex VALUES ('virt_nodes','ips','text','regex','^(\\d{1,2}:\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3} {0,1})*$',0,2048,NULL);
REPLACE INTO table_regex VALUES ('virt_nodes','osname','text','redirect','os_info:osname',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_nodes','cmd_line','text','redirect','default:tinytext',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_nodes','rpms','text','regex','^([-\\w\\.\\/\\+:~]+;{0,1})*$',0,4096,NULL);
......@@ -970,6 +970,14 @@ REPLACE INTO table_regex VALUES ('user_pubkeys','verify','text','redirect','defa
REPLACE INTO table_regex VALUES ('user_pubkeys','user','text','redirect','users:uid',0,0,NULL);
REPLACE INTO table_regex VALUES ('user_pubkeys','keyfile','text','regex','^[-_\\w\\.\\/:+]*$',1,256,NULL);
REPLACE INTO table_regex VALUES ('virt_paths','pathname','text','redirect','virt_nodes:vname',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_paths','segmentname','text','redirect','virt_nodes:vname',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_paths','segmentindex','int','redirect','default:tinyuint',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_paths','layer','int','redirect','default:tinyint',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','implemented_by_path','text','redirect','virt_paths:pathname',1,128,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','implemented_by_link','text','redirect','default:tinytext',0,0,NULL);
REPLACE INTO table_regex VALUES ('elabinelab_attributes','role','text','regex','^(boss|router|ops|fs|node)$',0,0,NULL);
REPLACE INTO table_regex VALUES ('elabinelab_attributes','attrkey','text','regex','^[-\\w\\.]+$',1,32,NULL);
REPLACE INTO table_regex VALUES ('elabinelab_attributes','attrvalue','text','regex','^[-\\w\\.\\+,\\s\\/]+$',0,255,NULL);
......
#
# Add virt_paths
#
use strict;
use libdb;
sub DoUpdate($$$)
{
my ($dbhandle, $dbname, $version) = @_;
if (!DBTableExists("virt_paths")) {
DBQueryFatal("CREATE TABLE `virt_paths` ( ".
" `pid` varchar(12) NOT NULL default '', ".
" `eid` varchar(32) NOT NULL default '', ".
" `exptidx` int(11) NOT NULL default '0', ".
" `pathname` varchar(32) NOT NULL default '', ".
" `segmentname` varchar(32) NOT NULL default '', ".
" `segmentindex` tinyint(4) unsigned NOT NULL default '0', ".
" `layer` tinyint(4) NOT NULL default '0', ".
" PRIMARY KEY (`exptidx`,`pathname`,`segmentname`), ".
" UNIQUE KEY `segidx` (`exptidx`,`pathname`,`segmentindex`), ".
" KEY `pid` (`pid`,`eid`,`pathname`), ".
" KEY `pideid` (`pid`,`eid`,`pathname`,`segmentname`) ".
") ENGINE=MyISAM DEFAULT CHARSET=latin1");
}
DBQueryFatal("REPLACE INTO table_regex VALUES" .
" ('virt_paths', 'pathname', 'text', 'redirect', ".
" 'virt_nodes:vname', 0,0,NULL)");
DBQueryFatal("REPLACE INTO table_regex VALUES" .
" ('virt_paths', 'segmentname', 'text', 'redirect', ".
" 'virt_nodes:vname', 0,0,NULL)");
DBQueryFatal("REPLACE INTO table_regex VALUES" .
" ('virt_paths', 'segmentindex', 'int', 'redirect', ".
" 'default:tinyuint', 0,0,NULL)");
DBQueryFatal("REPLACE INTO table_regex VALUES" .
" ('virt_paths', 'layer', 'int', 'redirect', ".
" 'default:tinyint', 0,0,NULL)");
if (!DBSlotExists("virt_lans", "implemented_by_path")) {
DBQueryFatal("ALTER TABLE virt_lans ADD ".
" `implemented_by_path` tinytext");
}
if (!DBSlotExists("virt_lans", "implemented_by_link")) {
DBQueryFatal("ALTER TABLE virt_lans ADD ".
" `implemented_by_link` tinytext");
}
DBQueryFatal("REPLACE INTO table_regex VALUES" .
" ('virt_lans', 'implemented_by_path', 'text', 'redirect', ".
" 'virt_paths:pathname', 1,128,NULL)");
DBQueryFatal("REPLACE INTO table_regex VALUES" .
" ('virt_lans', 'implemented_by_link', 'text', 'redirect', ".
" 'default:tinytext', 0,0,NULL)");
# Unrelated bug fix.
DBQueryFatal("REPLACE INTO table_regex VALUES ".
" ('virt_nodes','ips','text','regex', ".
" '^(\\\\d{1,2}:\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3} {0,1})*\$',".
" 0,2048,NULL)");
return 0;
}
1;
......@@ -24,6 +24,7 @@ use libtestbed;
use libreboot;
use libosload;
use Node;
use NodeType;
use libtblog;
use English;
use Data::Dumper;
......@@ -781,9 +782,16 @@ sub NewType($$)
#
# These special cases will eventually be encoded in the DB.
# Note that type might be a class, and so Lookup() returns nothing.
#
$type = "protogeni"
if ($type eq "pcfedphys" || $type eq "pcfed");
my $typeinfo = NodeType->Lookup($type);
if ($type eq "pcfedphys" || $type eq "pcfed") {
$type = "protogeni";
}
elsif (defined($typeinfo) && $typeinfo->issubnode()) {
$type = "subnode";
}
my $packname = "libossetup_${type}";
my $newtype = eval { $packname->New($self); };
......@@ -812,8 +820,12 @@ sub TypeLookup($$)
#
# These special cases will eventually be encoded in the DB.
#
$type = "protogeni"
if ($type eq "pcfedphys" || $type eq "pcfed");
if ($type eq "pcfedphys" || $type eq "pcfed") {
$type = "protogeni";
}
elsif ($node->issubnode()) {
$type = "subnode";
}
return $self->{'TYPECACHE'}->{$type}
if (exists($self->{'TYPECACHE'}->{$type}));
......@@ -1517,6 +1529,36 @@ use English;
use Data::Dumper;
use overload ('""' => 'Stringify');
#
# A constructor for an object to handle all nodes of this type.
#
sub New($$) {
my ($class, $parent) = @_;
my $self = $class->SUPER::New("subnode", $parent);
bless($self, $class);
return $self;
}
sub AddNode($$)
{
my ($self, $node) = @_;
print "Will skip subnode $node ISUP wait.\n";
return $self->SUPER::AddNode($node);
}
#
# We do not currently do anything with subnodes; no waiting for ISUP.
#
sub Volunteers($)
{
my ($self) = @_;
return ();
}
#####################################################################
#
# All protogeni nodes.
......
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2006 University of Utah and the Flux Group.
# Copyright (c) 2000-2010 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -19,7 +19,7 @@ LIB_STUFF = lanlink.tcl node.tcl sim.tcl tb_compat.tcl null.tcl \
nsenode.tcl nstb_compat.tcl event.tcl firewall.tcl \
elabinelab.ns elabinelab-withfsnode.ns \
fw.ns timeline.tcl sequence.tcl \
topography.tcl console.tcl
topography.tcl console.tcl path.tcl
BOSSLIBEXEC = parse-ns
USERLIBEXEC = parse.proxy
......
......@@ -214,8 +214,9 @@ LanLink instproc init {s nodes bw d type} {
# XXX Allow user to set the accesspoint.
$self set accesspoint {}
# Optional layer
# Optional layer and implemented-by relationship
$self set layer {}
$self set implemented_by {}
# A simulated lanlink unless we find otherwise
$self set simulated 1
......@@ -324,6 +325,37 @@ Link instproc trace {{ttype "header"} {texpr ""}} {
$fromqueue trace $ttype $texpr
}
#
# A link can be implemented in terms of a path or
# a link at a lower level of the stack.
#
Link instproc implemented_by {impl} {
$self instvar implemented_by
$self instvar layer
if {[$impl info class] == "Path"} {
set implemented_by $impl
} elseif {[$impl info class] == "Link"} {
if {$layer == {}} {
perror "\[$self implemented_by] no layer set!"
return
}
set impl_layer [$impl set layer]
if {$impl_layer == {}} {
perror "\[$self implemented_by] no layer set in $impl!"
return
}
if {$impl_layer >= $layer} {
perror "\[$self implemented_by] $impl is not at a lower layer!"
return
}
set implemented_by $impl
} else {
perror "\[$self implemented_by] must be a link or a path!"
return
}
}
Lan instproc trace_snaplen {len} {
$self instvar nodelist
$self instvar linkq
......@@ -720,6 +752,7 @@ Link instproc updatedb {DB} {
$self instvar mustdelay
$self instvar fixed_iface
$self instvar layer
$self instvar implemented_by
$sim spitxml_data "virt_lan_lans" [list "vname"] [list $self]
......@@ -810,6 +843,13 @@ Link instproc updatedb {DB} {
if { $layer != {} } {
lappend fields "layer"
}
if { $implemented_by != {} } {
if {[$implemented_by info class] == "Path"} {
lappend fields "implemented_by_path"
} else {
lappend fields "implemented_by_link"
}
}
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 $node $port $ip $mustdelay]
......@@ -839,6 +879,9 @@ Link instproc updatedb {DB} {
if { $layer != {} } {
lappend values $layer